Поэтапное распределение строк (sql)

У меня имеется задача с поэтапным неравномерным распределением. Имеется 2 таблицы в одной хранятся id пользователей и даты, в другой таблицы проекты и количество id пользователей, которых необходимо раскидать по этим проектам. Сложность заключается в том, что чтобы распределить пользователей честно, необходимо распределять их поочередно, т.е. если у нас три проекта - 1 пользователя на 1 проект, 2 на 2, 3 на 3, 4 на 1, 5 на 2, 6 на 3, 7 на 1 и т.д. Если необходимое количество количество id для одного из проектов было выбрано, необходимо продолжить распределение, но уже на количество оставшихся проектов, в данном примере - 2. Количество проектов во второй таблице может изменяться, но не более 10. Единственно решение, которое я придумал - это присвоить ранг для проектов по возрастанию, далее пронумеровать таблицу исходя из количества проектов (прим. 1, 2, 3, 1, 2, 3 и т.д.), а когда количество для самого малого выбирается, повторить процедуру но уже с количеством проектов на 1 меньше. Сложность этого метода в слишком большом количестве вложенных запросов, что сильно замедляет снижает скорость работы. Подскажите есть ли варианты написать это проще и дешевле?

Пример таблиц

Пример логики запроса:

    with rank as (
    select project,
           count,
           row_number() over (order by count) as rank_projects
)
select id,
       count,
       project_number,
       rank_projects,
       case
           when row_number() over (order by date) <= count and rank_projects = 3
               then t4.project_number = 'project 3'
           end
from (
         select id,
                count,
                project_number,
                rank_projects,
                case
                    when row_number() over (partition by by_all_projects_2) < = count and rank_projects = 2
                        then project_number = 'project_2'
                    end as project_number
         from (select id,
                      count,
                      project_number,
                      rank_projects,
                      case
                          row_number() over (order by date) % count(distinct project) - 1 = 0
                          then 1 else row_number() over (order by date) % count(distinct project) - 1
                          end as by_all_projects_2

               from (
                   select id,
                   count,
                   rank_projects,
                   case
                   when row_number() over (partition by by_all_projects) < = count and rank_projects = 1
                   then 'project_1'
                   end as project_number
                   from (
                   select id,
                   rank_projects,
                   count,
                   case
                   when row_number() over (order by date) % count(distinct project) = 0 then 1
                   else row_number() over (order by date) % count(distinct project)
                   end as by_all_projects
                   from id
                   cross join rank
                   ) as t1
                   ) as t2
              ) as t3
         where project_number is null
     ) as t4
where project_number is null

Ответы (0 шт):