:
DECLARE @T TABLE (Start INT, [End] INT, Value VARCHAR(100));
INSERT @T (Start, [End], Value)
VALUES
(0, 1, 'Banana'), (1, 3, 'Banana'), (3, 4, 'Orange'), (4, 7, 'Orange'),
(7, 8, 'Apple'), (8, 9, 'Apple'), (9, 10, 'Apple'), (10, 15, 'Apple'),
(20, 22, 'Apple'), (22, 23, 'Apple'), (23, 28, 'Banana'), (28, 30, 'Banana');
WITH CTE AS
( SELECT t.[Start],
t.[End],
t.[value],
IsStart = ISNULL(c.IsStart, 1)
FROM @T AS T
OUTER APPLY
( SELECT TOP 1 IsStart = 0
FROM @T AS T2
WHERE T2.Value = T.Value
AND T2.[End] = T.Start
) AS c
)
SELECT Value, Start = MIN(Start), [End] = MAX([End])
FROM CTE AS T
OUTER APPLY
( SELECT SUM(IsStart)
FROM CTE AS T2
WHERE T2.Value = T.Value
AND T2.Start <= T.Start
) g (GroupingSet)
GROUP BY Value, GroupingSet
ORDER BY Start;
- , . :
SELECT t.[Start],
t.[End],
t.[value],
IsStart = ISNULL(c.IsStart, 1)
FROM @T AS T
OUTER APPLY
( SELECT TOP 1 IsStart = 0
FROM @T AS T2
WHERE T2.Value = T.Value
AND T2.[End] = T.Start
) AS c
:
Start End value IsStart
0 1 Banana 1
1 3 Banana 0
3 4 Orange 1
4 7 Orange 0
7 8 Apple 1
8 9 Apple 0
9 10 Apple 0
10 15 Apple 0
20 22 Apple 1
, , , IsStart, . :
SELECT *
FROM CTE AS T
OUTER APPLY
( SELECT SUM(IsStart)
FROM CTE AS T2
WHERE T2.Value = T.Value
AND T2.Start <= T.Start
) g (GroupingSet);
:
Start End value IsStart GroupingSet
0 1 Banana 1 1
1 3 Banana 0 1
3 4 Orange 1 1
4 7 Orange 0 1
7 8 Apple 1 1
8 9 Apple 0 1
9 10 Apple 0 1
10 15 Apple 0 1
20 22 Apple 1 2 -- SECOND NON CONTINUOUS RANGE FOR APPLES
22 23 Apple 0 2
23 28 Banana 1 2 -- SECOND NON CONTINUOUS RANGE FOR BANANAS
28 30 Banana 0 2
, .
, ( master..spt_values):
WITH CTE AS
( SELECT t.[value],
Number = t.Start + v.Number,
GroupingSet = t.Start + v.Number - ROW_NUMBER() OVER(PARTITION BY t.[value] ORDER BY t.Start + v.Number)
FROM @T AS T
INNER JOIN Master..spt_values v
ON v.[Type] = 'P'
AND v.Number < (t.[End] - t.[Start])
)
SELECT Value, [Start] = MIN(Number), [End] = MAX(Number)
FROM CTE
GROUP BY GroupingSet, Value;
, , , , / . , , -