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

SQL Server, znajdź dowolną sekwencję wartości

Spowoduje to wybranie wszystkich klientów z co najmniej dwoma kolejnymi działaniami tego samego typu.

WITH    rows AS 
        (
        SELECT  customer, action,
                ROW_NUMBER() OVER (PARTITION BY customer ORDER BY lastlogin) AS rn
        FROM    mytable
        )
SELECT  DISTINCT customer
FROM    rows rp
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    rows rl
        WHERE   rl.customer = rp.customer
                AND rl.rn = rp.rn + 1
                AND rl.action = rp.action
        )

Oto bardziej wydajne zapytanie dla samego działania 2 :

WITH    rows AS 
        (
        SELECT  customer, ROW_NUMBER() OVER (PARTITION BY customer ORDER BY lastlogin) AS rn
        FROM    mytable
        WHERE   action = 2
        )
SELECT  DISTINCT customer
FROM    rows rp
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    rows rl
        WHERE   rl.customer = rp.customer
                AND rl.rn = rp.rn + 1
        )

Aktualizacja 2:

Aby wybrać nieprzerwane zakresy:

WITH    rows AS 
        (
        SELECT  customer, action, lastlogin
                ROW_NUMBER() OVER (PARTITION BY customer ORDER BY lastlogin) AS rn
                ROW_NUMBER() OVER (PARTITION BY customer, action ORDER BY lastlogin) AS series
        FROM    mytable
        )
SELECT  DISTINCT customer
FROM    (
        SELECT  customer
        FROM    rows rp
        WHERE   action
        GROUP BY
                customer, actioncode, series - rn
        HAVING
                DETEDIFF(day, MIN(lastlogin), MAX(lastlogin)) >= 14
        ) q

To zapytanie oblicza dwie serie:jedna zwraca ciągły ORDER BY lastlogin , druga partycja przez action dodatkowo:

action  logindate rn  series diff = rn - series
1       Jan 01    1   1      0
1       Jan 02    2   2      0
2       Jan 03    3   1      2
2       Jan 04    4   2      2
1       Jan 05    5   3      2
1       Jan 06    6   4      2

Dopóki różnica między tymi dwoma schematami jest taka sama, serie są nieprzerwane. Każde przerwanie przerywa serię.

Oznacza to, że kombinacja (action, diff ) definiuje nieprzerwane grupy.

Możemy grupować według action, diff , znajdź MAX i MIN w grupach i filtruj je.

Jeśli potrzebujesz wybrać 14 wierszy zamiast 14 kolejne dni, po prostu filtruj według COUNT(*) zamiast DATEDIFF .



  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 usunąć wszystkie ograniczenia klucza obcego we wszystkich tabelach?

  2. Jak skopiować tabele unikając kursorów w SQL?

  3. Jakie są zalety MERGE nad prostym JEŻELI ISTNIEJE?

  4. rozwiązywanie problemu z kursorami

  5. Jak skonfigurować pocztę bazy danych w programie SQL Server (SSMS)