(단일 행)출석 도장. 1월·2월·3월 쭉 찍었으면 3연속. 1월·3월만 찍었으면 끊긴 것. 이 트릭은 외워 두면 평생 쓴다.
| 결제한 달 | 달 번호 | 줄 번호 | 차이 |
|---|---|---|---|
| 1월 | 1 | 1 | 0 |
| 2월 | 2 | 2 | 0 |
| 3월 | 3 | 3 | 0 |
| 6월 | 6 | 4 | 2 |
차이가 같은 것끼리 한 덩어리다. 위에서는 0 이 세 개니까 3연속. 연속이면 달 번호와 줄 번호가 똑같이 1씩 늘어서 차이가 안 변한다. 끊기면 달 번호만 껑충 뛰어서 차이가 달라진다.
묻는 것 · gaps and islands. 알면 1분, 모르면 못 푼다.
일련번호 − ROW_NUMBER() → 연속 구간마다 같은 값이 나온다.WITH mu AS (
SELECT DISTINCT user_id, DATE_FORMAT(paid_date, '%Y-%m-01') AS m FROM payments
),
g AS (
SELECT user_id, m,
TIMESTAMPDIFF(MONTH, '2026-01-01', m)
- ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY m) AS grp
FROM mu
),
runs AS (
SELECT user_id, grp, COUNT(*) AS run_len FROM g GROUP BY user_id, grp
)
SELECT COUNT(DISTINCT user_id) AS users_with_3plus_streak
FROM runs WHERE run_len >= 3;2,3,4월 → 1,2,3 − 1,2,3 = 0,0,0 (같은 그룹)2월, 5월 → 1,4 − 1,2 = 0,2 (다른 그룹)DISTINCT)를 안 하면 같은 달 두 번 결제한 유저가 연속으로 잘못 잡힌다.COUNT(DISTINCT user_id) — 한 유저가 연속 구간을 두 개 가질 수 있다.“연속 출석 일수”, “N일 연속 접속” 전부 동일. 일 단위면 DATEDIFF 를 일련번호로.