问题
I have a table containing the below test data:
I now would like to fill a restaurant with 12 seating spaces.
This should result in:
Basically, I need to loop from top to bottom through all rows and add the AmountPersons until I have filled the restaurant.
In this example:
(first few rows: AmountPersons) 3+1+2+4 = 10
UserId 52 can't be added because they reserved for 3 persons, which would result in 13 occupied places and there are only 12 available.
In the next row it notices a reservation for 1. This can be added to the previous 10 we already found.
NewTotal is now 11.
UserId 79 and 82 can't be added because we'd exceed the capacity again.
UserId 95 reserved for 1, this one can be added and we now have all places filled.
This is the result I get from the cursor I use, but I'm stuck now. Please help.
The while loop I have in the cursor basically stops when the next value would be higher than 12. But that is not correct.
回答1:
Because you want to skip rows, you need a recursive CTE. But it is tricky -- because you may not have a group following your rules that adds up to exactly 12.
So:
with tn as (
select t.*, row_number() over (order by userid) as seqnum
from t
),
cte as (
select userId, name, amountPersons as total, 1 as is_included, seqnum
from tn
where seqnum = 1
union all
select tn.userId, tn.name,
(case when tn.amountPersons + cte.total <= 12
then tn.amountPersons + cte.total
else cte.total
end),
(case when tn.amountPersons + cte.total <= 12
then 1
else 0
end) as is_included,
tn.seqnum
from cte join
tn
on tn.seqnum = cte.seqnum + 1
where cte.total < 12
)
select cte.*
from cte
where is_included = 1;
Here is a db<>fiddle.
Note that if you change "I" to a larger value, then it is not included and the number of occupied seats is 11, not 12.
来源:https://stackoverflow.com/questions/62129188/t-sql-loop-through-all-rows-and-sum-amount-from-column-until-value-is-reached