Thao tác này sẽ chọn tất cả khách hàng có ít nhất hai hành động liên tiếp cùng loại.
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
)
Đây là truy vấn hiệu quả hơn cho chỉ hành động 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
)
Cập nhật 2:
Để chọn phạm vi không bị gián đoạn:
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
Truy vấn này tính toán hai chuỗi:một chuỗi trả về ORDER BY lastlogin
, cái thứ hai phân vùng bằng action
ngoài ra:
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
Miễn là sự khác biệt giữa hai chương trình giống nhau, thì chuỗi không bị gián đoạn. Mỗi lần gián đoạn sẽ phá vỡ chuỗi.
Điều này có nghĩa là sự kết hợp của (action, diff
) xác định các nhóm không bị gián đoạn.
Chúng ta có thể nhóm theo action, diff
, tìm MAX
và MIN
trong các nhóm và lọc chúng.
Nếu bạn cần chọn 14
hàng thay vì 14
các ngày liên tiếp, chỉ cần lọc trên COUNT(*)
thay vì DATEDIFF
.