Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak identyfikować sekwencje wzorców rekordów w rekordach przy użyciu TSQL?

Możesz użyć następującego zapytania opakowanego w CTE aby przypisać numery sekwencji do wartości zawartych w sekwencji:

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

Wyjście:

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

Korzystanie z powyższego CTE możesz zidentyfikować wyspy, tj. plasterki kolejnych wierszy zawierających całą sekwencję:

;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

Wyjście:

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

grp pole pomaga dokładnie zidentyfikować te wyspy.

Wszystko, co musisz teraz zrobić, to po prostu odfiltrować częściowe grupy:

;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

Pokaz tutaj

Uwaga: W początkowej wersji tej odpowiedzi użyto INNER JOIN do Seq . To nie zadziała, jeśli tabela zawiera wartości takie jak 5, 42, 9, 6 , jak 42 zostanie odfiltrowany przez INNER JOIN i ta sekwencja została błędnie zidentyfikowana jako poprawna. Za tę edycję zasługuje @HABO.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak mogę wykonać wyzwalacz PRZED AKTUALIZACJĄ z serwerem sql?

  2. Zmień nazwę tabeli w SQL Server (T-SQL)

  3. Jak połączyć się z mssql za pomocą pdo przez PHP i Linux?

  4. Scal dane w dwie tabele docelowe

  5. Jak mogę debugować EXCEPTION_ACCESS_VIOLATION w SQL Server 2008?