我正在努力做到这一点,因为它涉及比较连续的行。我正在尝试将相差一定数值的值进行分组。例如,让我们说我有这个表:
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而被归入同一组。我将首先展示我的尝试:
(3,1) (3,2) (3,3) (3,4)
(8,3) (8,4) (8,5) (8,6)
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
我将在一个大表(大约3000万行)上执行此操作,因此我希望有一个更好的方法可以对任意值执行此操作(例如,不仅可以相差1,还可以是2或3,稍后合并到程序中)。关于我的方法是否没有错误以及是否可以改进的任何建议?
declare @Diff int = 1 ;with C as ( select A, B, row_number() over(partition by A order by B) as rn from #TEMP ), R as ( select C.A, C.B, 1 as G, C.rn from C where C.rn = 1 union all select C.A, C.B, G + case when C.B-R.B <= @Diff then 0 else 1 end, C.rn from C inner join R on R.rn + 1 = C.rn and R.A = C.A ) select A, B, dense_rank() over(order by A, G) as G from R order by A, G