Dette vil vælge alle kunder med mindst to på hinanden følgende handlinger af samme type.
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
)
Her er den mere effektive forespørgsel til blot handling 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
)
Opdatering 2:
Sådan vælger du uafbrudte områder:
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
Denne forespørgsel beregner to serier:den ene returnerer sammenhængende ORDER BY lastlogin
, den anden opdeler efter action
desuden:
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 forskellen mellem de to ordninger er den samme, er serierne uafbrudte. Hver afbrydelse bryder serien.
Det betyder, at kombinationen af (action, diff
) definerer de uafbrudte grupper.
Vi kan gruppere efter action, diff
, find MAX
og MIN
inden for grupperne og filtrer på dem.
Hvis du skal vælge 14
rækker i stedet for 14
på hinanden følgende dage, filtrer bare på COUNT(*)
i stedet for DATEDIFF
.