I have this data:
Start End Quantity
425 449 24
450 474 24
475 499 24
500 524 24
2300 2324 24
2400 2499 99
2500 2599 99
2800 2899 99
2900 2999 99
3200 3249 49
3250 3299 49
3300 3349 49
3350 3399 49
3400 3449 49
3500 3549 49
3600 3624 24
3650 3674 24
3700 3724 24
3950 3964 14
4000 4000 0
4150 4399 249
4400 4499 99
5034 5075 41
Quantity is a result of End - Start
.
I would like to obtain the following data, the Generated
rows:
Start End Quantity
425 449 24
450 474 24
475 499 24
500 524 24
425 524 96
2300 2324 24
2300 2324 24
2400 2499 99
2500 2599 99
-----GENERATED----
425 2599 438
------------------
2800 2899 99
2900 2999 99
3200 3249 49
3250 3299 49
3300 3349 49
3350 3399 49
3400 3449 49
3500 3549 49
-----GENERATED-----
2800 3549 492
------------------
3600 3624 24
3650 3674 24
3700 3724 24
3950 3964 14
4000 4000 0
4150 4399 249
4400 4499 99
5034 5075 41
-----GENERATED-----
3600 5075 475
------------------
The condition is that it has to sum all the quantities until 500. If it passes 500 do a new count.
I have tried with Rollup but I couldnt find the right condition to make it work.
Of course, this is way easier to do by programming code instead of SQL, but we must do it in database environment. The tools to get the generated rows can be anything, looping functions, new tables etc.
Error solving
I got into an error while running @Prdp's query:
Msg 530, Level 16, State 1, Line 1
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
I found the solution here: http://sqlhints.com/tag/the-statement-terminated-the-maximum-recursion-100-has-been-exhausted-before-statement-completion/
Update 1
Using @Prdp's query we got the following:
Start End rn st
(400) 424 1 24
425 449 2 48
450 474 3 72
475 499 4 96
500 524 5 120
2300 2324 6 144
2400 2499 7 243
2500 2599 8 342
2800 (2899) 9 (441)
(2900) 2999 10 99
3200 3249 11 148
3250 3299 12 197
3300 3349 13 246
3350 3399 14 295
3400 3449 15 344
3500 3549 16 393
3600 3624 17 417
3650 3674 18 441
3700 3724 19 465
3950 3964 20 479
4000 (4000) 21 (479)
(4150) 4399 22 249
4400 4499 23 348
5034 (5075) 24 (389)
Its getting closer to what we need. Would it be possible to extract only the data in between (
and )
while discarding the other data?
We can use cursors too.
You can use Recursive CTE
. I can't think of any better way.
;WITH cte
AS (SELECT *,
Row_number()OVER(ORDER BY start) rn
FROM Yourtable),
rec_cte
AS (SELECT *,
( [End] - Start ) AS st,
1 AS grp
FROM cte
WHERE rn = 1
UNION ALL
SELECT a.*,
CASE
WHEN st + ( a.[End] - a.Start ) >= 500 THEN a.[End] - a.Start
ELSE st + ( a.[End] - a.Start )
END,
CASE
WHEN st + ( a.[End] - a.Start ) >= 500 THEN b.grp + 1
ELSE grp
END
FROM cte a
JOIN rec_cte b
ON a.rn = b.rn + 1)
SELECT Min(Start) as Start,
Max([End]) as [End],
Max(st) as Quantity
FROM rec_cte
GROUP BY grp
OPTION (maxrecursion 0)