Name | Price | Qty |
---|---|---|
A | 3 | 30 |
B | 5 | 3 |
C | 5 | 3 |
D | 6 | 20 |
i have a table contain data like this. i want to get what is the maximum of sum(qty) that i can provide Price <= 100
expected output : 32
coming from : 30 qty A and 2 qty from B or C
Name | Price | Qty |
---|---|---|
A | 3 | 30 |
B | 5 | 3 |
C | 5 | 3 |
D | 6 | 20 |
i have a table contain data like this. i want to get what is the maximum of sum(qty) that i can provide Price <= 100
expected output : 32
coming from : 30 qty A and 2 qty from B or C
2
Answers
This can be solved by using a recursive common table expression to calculate a running total. I have used an initial cte to expand your data to one row per item (30 rows for item A, 3 rows for item B, etc) and have ordered these by cost. The recursive part of the query the loops through each of these in order until the total price reaches 100.
First, get a rolling sum of quantity and price * quantity. Use a window ordered by price to ensure you spend your money on the best deals first. Since price is not unique, we can also order by the primary key (I’m using name) to ensure consistent results.
Use
lead
to keep track of the next possible option, price, and available quantity.At this point we have all the information we need to finish the calculation.
100 - "running cost"
is the "remaining money"floor( "remaining money" / "next price" )
is the "next purchased""next price" * "next purchased"
is the "next cost"100 - "running cost" - "next cost"
is the "remaining money"It might be easier to do the final calculation outside of SQL using the results, or you can finish up in SQL…
Use a CTE to pick the row closest to, but not over, your limit and calculate how many can be purchased with your remainder.
Finally, use another CTE to sum this all up and calculate how much money is left over.
This might have performance advantages over a recursive approach.
Demonstration.