sql >> データベース >  >> RDS >> Sqlserver

TSQL を使用して、レコード内のレコード パターン シーケンスをどのように識別しますか?

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



    1. SQLite Python

    2. PHPMySqlを使用した高度なニュースアーカイブの年/月

    3. PHP / MySQL:過去*全*週のエントリを取得しています

    4. SSLを介したPHPMySQL。ピア証明書が一致しませんでした