sql >> Databasteknik >  >> RDS >> Sqlserver

Hur identifierar du postmönstersekvenser i poster med TSQL?

Du kan använda följande fråga insvept i en CTE för att tilldela sekvensnummer till värdena i din sekvens:

;WITH Seq AS (
    SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn
    FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k,v)
)

Utdata:

v   rn
-------
5   1
9   2
6   3

Använd ovanstående CTE du kan identifiera öar, d.v.s. delar av sekventiella rader som innehåller hela sekvensen:

;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 [Key], [Value], 
       ROW_NUMBER() OVER (ORDER BY [Key]) - rn AS grp            
FROM mytable AS m
LEFT JOIN Seq AS s ON m.Value = s.v
)
SELECT *
FROM Grp

Utdata:

    Key Value   grp
   -----------------
    1   5       0
    2   9       0
    3   6       0
    6   5       3
    7   9       3
    8   6       3

grp fältet hjälper dig att identifiera exakt dessa öar.

Allt du behöver göra nu är att bara filtrera bort partiella grupper:

;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 [Key], [Value], 
       ROW_NUMBER() OVER (ORDER BY [Key]) - rn AS grp            
FROM mytable AS m
LEFT JOIN Seq AS s ON m.Value = s.v
)
SELECT g1.[Key], g1.[Value]
FROM Grp AS g1
INNER JOIN (
   SELECT grp
   FROM Grp
   GROUP BY grp
   HAVING COUNT(*) = 3 ) AS g2
ON g1.grp = g2.grp

Demo här

Obs! Den ursprungliga versionen av detta svar använde en INNER JOIN till Seq . Detta fungerar inte om tabellen innehåller värden som 5, 42, 9, 6 , som 42 kommer att filtreras bort av INNER JOIN och denna sekvens felaktigt identifierad som en giltig. Tack till @HABO för denna redigering.



  1. Installera MySQL JDBC-drivrutiner i Pentaho Data Integration och BA Server-verktyg

  2. Bestämning av radien eller diametern för en minsta begränsningscirkel

  3. mysqli_stmt_get_result alternativ för php 5.2.6

  4. Fyll i Django-databas