CTE
でラップされた次のクエリを使用できます シーケンスに含まれる値にシーケンス番号を割り当てるには:
;WITH Seq AS ( SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k, v))コード> プレ>
出力:
v rn-------5 19 26 3
プレ>
上記の CTE
を使用する 島、つまりシーケンス全体を含む連続した行のスライスを識別できます:
;WITH Seq AS ( SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k, v)), Grp AS (SELECT [キー], [値], ROW_NUMBER() OVER (ORDER BY [キー]) - rn AS grp FROM mytable AS mLEFT JOIN Seq AS s ON m.Value =s.v)SELECT *FROM Grp コード> プレ>
出力:
キー値 grp ----------------- 1 5 0 2 9 0 3 6 0 6 5 3 7 9 3 8 6 3
プレ>
グループ
フィールドは、これらの島々を正確に識別するのに役立ちます。
あとは、部分的なグループを除外するだけです:
;WITH Seq AS ( SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k, v)), Grp AS (SELECT [キー], [値], ROW_NUMBER() OVER (ORDER BY [キー]) - rn AS grp FROM mytable AS mLEFT JOIN Seq AS s ON m.Value =s.v)SELECT g1.[ Key], g1.[Value] FROM Grp AS g1INNER JOIN ( SELECT grp FROM Grp GROUP BY grp HAVING COUNT(*) =3 ) AS g2ON g1.grp =g2.grp
プレ>
注: この回答の最初のバージョンでは、 INNER JOIN
を使用していました Seq
へ .テーブルに 5, 42, 9, 6
のような値が含まれている場合、これは機能しません 、 42
として INNER JOIN
によって除外されます そして、このシーケンスは有効なものとして誤って識別されました。この編集は @HABO の功績によるものです。