我有这些数据:
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
数量是End - Start
的结果。
我想获取以下数据:Generated
行:
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
------------------
条件是它必须将所有数量相加到500.如果它超过500则执行新的计数。
我尝试使用Rollup,但我无法找到使其正常工作的正确条件。
当然,通过编程代码而不是SQL,这样做更容易,但我们必须在数据库环境中这样做。获取生成的行的工具可以是任何东西,循环函数,新表等。
解决错误
我在运行@ Prdp的查询时遇到错误:
Msg 530, Level 16, State 1, Line 1
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
更新1
使用@ Prdp的查询我们得到以下内容:
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)
它越来越接近我们需要的东西了。是否可以在丢弃其他数据的同时仅提取(
和)
之间的数据?
我们也可以使用游标。
答案 0 :(得分:2)
您可以使用Recursive CTE
。我无法想到更好的方法。
;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)
答案 1 :(得分:-1)
这是MySQL中提出的解决方案。类似的策略应该在SQL Server中有效。
drop table if exists TestData;
create table TestData(Start int, End int, Quantity int);
insert TestData values (425,449,24);
insert TestData values (450,474,24);
insert TestData values (475,499,24);
insert TestData values (500,524,24);
insert TestData values (2300,2324,24);
insert TestData values (2400,2499,99);
insert TestData values (2500,2599,99);
insert TestData values (2800,2899,99);
insert TestData values (2900,2999,99);
insert TestData values (3200,3249,49);
insert TestData values (3250,3299,49);
insert TestData values (3300,3349,49);
insert TestData values (3350,3399,49);
insert TestData values (3400,3449,49);
insert TestData values (3500,3549,49);
insert TestData values (3600,3624,24);
insert TestData values (3650,3674,24);
insert TestData values (3700,3724,24);
insert TestData values (3950,3964,14);
insert TestData values (4000,4000,0);
insert TestData values (4150,4399,249);
insert TestData values (4400,4499,99);
insert TestData values (5034,5075,41);
drop table if exists DataRange;
create table DataRange (StartRange int, EndRange int);
insert DataRange values (425, 2599);
insert DataRange values (2800,3549);
insert DataRange values (3600,5075);
select
DataRange.StartRange,DataRange.EndRange
,sum(TestData.quantity) as Quantity
from TestData
inner join DataRange on
(TestData.start between DataRange.StartRange and DataRange.EndRange )
or
(TestData.End between DataRange.StartRange and DataRange.EndRange )
group by DataRange.StartRange,DataRange.EndRange