Скажем, у меня есть список статей, которые я хочу разбить, чтобы заполнить максимальные значения:

id | name  | quantity | maxquantity
1  | name_a|        3 |           5
2  | name_a|        1 |           5
3  | name_a|        3 |           5
4  | name_a|        5 |           5
5  | name_b|        7 |           4
6  | name_b|        2 |           4

Я хочу создать пакеты, сгруппированные по имени, заполненные до максимальных значений, чтобы получить следующие результаты:

id | name  | quantity | maxquantity | tag          | effective_quantity 
1  | name_a|        3 |           5 | name_a_part1 |                  3
2  | name_a|        1 |           5 | name_a_part1 |                  1
3  | name_a|        3 |           5 | name_a_part1 |                  1
                                                                        ^- sum() = maxquantity

3  | name_a|        3 |           5 | name_a_part2 |                  2
4  | name_a|        5 |           5 | name_a_part2 |                  3
                                                                        ^- sum() = maxquantity

4  | name_a|        5 |           5 | name_a_part3 |                  2
                                                                        ^- sum() = maxquantity or the rest of name_a

5  | name_b|        7 |           4 | name_b_part1 |                  4
                                                                        ^- sum() = maxquantity

5  | name_b|        7 |           4 | name_b_part2 |                  3
6  | name_b|        2 |           4 | name_b_part2 |                  1
                                                                        ^- sum() = maxquantity

6  | name_b|        2 |           4 | name_b_part3 |                  1
                                                                        ^- sum() = maxquantity or the rest of name_b
         
1
macfly 17 Сен 2021 в 14:10

1 ответ

Лучший ответ

Один довольно простой метод - выделить данные в отдельную строку для каждого элемента, вычислить ячейки на этом уровне и затем повторно агрегировать:

with cte (id, name, quantity, maxquantity, n) as (
      select id, name, quantity, maxquantity, 1 as n
      from t
      union all
      select id, name, quantity, maxquantity, n + 1
      from cte
      where n < quantity
     ) 
select id, name, quantity, maxquantity,
       count(*) as number_in_bin,
       ceil(bin_counter / maxquantity) as bin_number
from (select cte.*,
             row_number() over (partition by name order by id, n) as bin_counter
      from cte
     ) cte
group by id, name, quantity, maxquantity, ceil(bin_counter / maxquantity) 
order by id, bin_number;

Вот скрипка db <>.

0
Gordon Linoff 17 Сен 2021 в 11:50