Получение всех последовательных строк, различающихся определенным значением?

Я пытаюсь осознать это, поскольку это включает в себя сравнение последовательных строк. Я пытаюсь сгруппировать значения, которые отличаются на определенное число. Например, предположим, что у меня есть эта таблица:

CREATE TABLE #TEMP (A int, B int)

-- Sample table
INSERT INTO #TEMP VALUES 
(3,1), 
(3,2), 
(3,3),
(3,4),
(5,1),
(6,1),
(7,2),
(8,3),
(8,4),
(8,5),
(8,6)

SELECT * FROM #TEMP

DROP TABLE #TEMP

И позвольте нам сгруппировать все значения, которые отличаются на 1, имеющими одинаковое значение для A. Затем я пытаюсь получить такой вывод:

A B GroupNo
3 1 1
3 2 1
3 3 1
3 4 1
5 1 2
6 1 3
7 2 4
8 3 5
8 4 5
8 5 5
8 6 5

( 3,1) (3,2) (3,3) (3,4) и (8,3) (8,4) (8,5) (8,6) имеют помещены в одну группу, потому что они различаются на значение 1. Сначала я покажу свою попытку:

CREATE TABLE #TEMP (A int, B int)

-- Sample table
INSERT INTO #TEMP VALUES 
(3,1), (3,2), (3,3), (3,4), (5,1), (6,1), (7,2),
(8,3), (8,4), (8,5), (8,6)

-- Assign row numbers and perform a left join
-- so that we can compare consecutive rows
SELECT ROW_NUMBER() OVER (ORDER BY A ASC) ID, * 
INTO #TEMP2
FROM #TEMP

;WITH CTE AS
(
    SELECT X.A XA, X.B XB, Y.A YA, Y.B YB
    FROM #TEMP2 X
    LEFT JOIN #TEMP2 Y
    ON X.ID = Y.ID - 1
    WHERE X.A = Y.A AND
    X.B = Y.B - 1
)
SELECT XA, XB
INTO #GROUPS
FROM CTE
UNION 
SELECT YA, YB
FROM CTE
ORDER BY XA ASC 

-- Finally assign group numbers
SELECT X.XA, X.XB, Y.GID
FROM #GROUPS X
INNER JOIN
(SELECT XA, ROW_NUMBER() OVER (ORDER BY XA ASC) GID
    FROM #GROUPS Y
    GROUP BY XA
) Y
ON X.XA = Y.XA

DROP TABLE #TEMP
DROP TABLE #TEMP2
DROP TABLE #GROUPS

Я буду делать это на большой таблице (около 30 миллионов строк), поэтому я надеялся, что есть лучший способ сделать это для произвольных значений (например, отличается не только на 1, но может быть 2 или 3, которые я позже включу в процедуру). Любые предложения относительно того, свободен ли мой подход от ошибок и можно ли его улучшить?

6
задан Legend 21 October 2011 в 20:21
поделиться