Input: consecutive numbers from 1 to 100 – 1,2,3,…,100
Desired output:
- 1st group: 1, 2, 3, 4, 5 -> sum 15 (not bigger than 20)
- 2nd group: 6, 7 -> sum 13 (not bigger than 20)
- 3rd group: 8, 9 -> sum 17 (not bigger than 20)
- 4th group: 10 -> sum 10 (not bigger than 20)
- 5th group: 11 -> sum 11 (not bigger than 20)
- …
- nth-1 group: 99 -> sum 99 (bigger than 20, but only one element)
- nth group: 100 -> sum 100 (bigger than 20, but only one element)
SELECT array_agg(n)
FROM generate_series(1, 100) as n
GROUP BY ... -- TODO -> Here's go magic grouping or other magic tricks
So I have consecutive numbers from 1 to 100, and I would like to group them in that way that sum in group is not bigger than 20 (if single number is bigger than 20 than new group with one element).
Edit:
Max number (in the example 100
) and max group’s sum (in the example 20
) are dynamic, so I cannot use hard coded solution
2
Answers
I started doing this:
which gives:
After the i tried creating a recursive CTE using above query, and only changing the
1
ingenerate_series(1,100)
After seeing lots of
NULL
values, and a reboot of my PostgreSQL server because of a memory error 😕😉… (probably caused bu programming mistakes on my site), I ended up with this (do note that some conditions are there for safety, to avoid thoseNULL
values and huge memory use)see: DBFIDDLE
result:
EDIT: A simpler, but more hard coded solution would be:
If the sequence is continuous, you can walk another
generate_series()
back a few numbers, keeping track of the current sum, then aggregate up to the element that exceeds it: demo