sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server, hitta en godtycklig sekvens av värden

Detta kommer att välja alla kunder med minst två på varandra följande åtgärder av samma typ.

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
        )

Här är den mer effektiva frågan för bara åtgärd 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
        )

Uppdatering 2:

För att välja oavbrutna intervall:

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

Den här frågan beräknar två serier:en returnerar sammanhängande ORDER BY lastlogin , den andra partitioneras med action dessutom:

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

Så länge skillnaden mellan de två systemen är densamma, är serierna oavbrutna. Varje avbrott bryter serien.

Detta innebär att kombinationen av (action, diff ) definierar de oavbrutna grupperna.

Vi kan gruppera efter action, diff , hitta MAX och MIN inom grupperna och filtrera på dem.

Om du behöver välja 14 rader istället för 14 dagar i följd, filtrera bara på COUNT(*) istället för DATEDIFF .



  1. Analysera Wiktionary XML-datadump till MySQL-databas med PHP

  2. Hur sammanfogar man kolumner i en Postgres SELECT?

  3. Ansluta till en OracleDB via en Android-app

  4. Att skapa en utvecklingsmiljö för att lära sig PL/SQL