2017-01-19 8 views
2

У меня есть эти данные:Группа строк по условию

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, но мы должны сделать это в среде базы данных. Инструменты, чтобы получить сформированные строки могут быть все что угодно, циклических функций, новые таблицы и т.д.

Ошибка решения

меня в ошибку при запуске @ запроса ППРР в:

Msg 530, Level 16, State 1, Line 1 
The statement terminated. The maximum recursion 100 has been exhausted before statement completion. 

Я нашел решение здесь: http://sqlhints.com/tag/the-statement-terminated-the-maximum-recursion-100-has-been-exhausted-before-statement-completion/

Update 1

Использование @ запроса ППРР в мы получили следующее:

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

просим использовать тег dbms, который вы используете. –

+0

@vkp Используемая база данных - sql-server-2005 – user7441876

+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) 
+0

это не совсем работает, так как не генерирует общие строки. Например, должна быть строка 425 2899 417. Если вы можете создать маркер группы для каждой группы, вы можете использовать rollup. Я могу придумать, как это сделать в последних версиях, но я не знаю, что есть и не разрешено в 2005 году. Конечно, вы можете использовать курсор, если вы не говорите никому –

+0

@AdamJacobson - Вы просто хотите эти три итоговые строки в результате? –

+0

@Prdp да, только 3 строки, другие данные «бесполезны». – user7441876

-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 
+0

Вы принимаете значения, которые он хочет рассчитать на fly –

+0

@AdamJacobson: Разве эти значения не должны быть где-то жестко закодированы? Почему бы не держать их в таблице? – jasonS

+0

@AdamJacobson: Я вижу сейчас. Спасибо за разъяснения. – jasonS

 Смежные вопросы

  • Нет связанных вопросов^_^