Поэтапное распределение строк (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
