Cela sélectionnera tous les clients avec au moins deux actions consécutives du même 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
)
Voici la requête la plus efficace pour l'action uniquement 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
)
Mise à jour 2 :
Pour sélectionner des plages ininterrompues :
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
Cette requête calcule deux séries :l'une renvoie ORDER BY lastlogin
contigus , le second partitionne par action
en plus :
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
Tant que la différence entre les deux schémas est la même, les séries sont ininterrompues. Chaque interruption casse la série.
Cela signifie que la combinaison de (action, diff
) définit les groupes ininterrompus.
Nous pouvons regrouper par action, diff
, trouvez MAX
et MIN
au sein des groupes et filtrez-les.
Si vous devez sélectionner 14
lignes plutôt que 14
jours consécutifs, filtrez simplement sur COUNT(*)
au lieu du DATEDIFF
.