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 の功績によるものです。