max_streak_days DESC, user_id ASCQ8 의 출석 도장 트릭과 똑같다. 단위가 '달' 에서 '날' 로 바뀐 것뿐.
| 거래한 날 | 날 번호 | 줄 번호 | 차이 |
|---|---|---|---|
| 3월 2일 | 60 | 1 | 59 |
| 3월 3일 | 61 | 2 | 59 |
| 3월 4일 | 62 | 3 | 59 |
| 3월 8일 | 66 | 4 | 62 |
차이 59 가 세 개 → 3연속. 그 다음은 끊긴 것.
최장일수 DESC, user_id ASC 둘 다 써라.묻는 것 · gaps and islands. 알면 2분, 모르면 못 푼다. 반드시 외워 둘 패턴.
SELECT DISTINCT user_id, order_date ... WHERE status='COMPLETED'. 이 한 줄에 문제의 조건 두 개가 다 들어 있다.DATEDIFF(order_date, '기준일').일련번호 − ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date) → 연속 구간마다 같은 값이 나온다.COUNT(*) → 구간 길이. 유저별 MAX() → 최장 길이. HAVING 으로 3 이상만.WITH d AS (
SELECT DISTINCT user_id, order_date
FROM stock_orders
WHERE status = 'COMPLETED'
),
g AS (
SELECT user_id, order_date,
DATEDIFF(order_date, '2026-01-01')
- ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date) AS grp
FROM d
),
runs AS (
SELECT user_id, grp, COUNT(*) AS run_len
FROM g GROUP BY user_id, grp
)
SELECT user_id, MAX(run_len) AS max_streak_days
FROM runs
GROUP BY user_id
HAVING MAX(run_len) >= 3
ORDER BY max_streak_days DESC, user_id ASC;3/2,3/3,3/4 → 60,61,62 − 1,2,3 = 59,59,59 (한 구간)3/2, 3/6 → 60,64 − 1,2 = 59,62 (다른 구간)WHERE run_len >= 3 으로 미리 걸러도 같은 답이 나오지만, 그러면 '최장 구간이 3 미만인 유저' 와 '3 이상 구간만 남긴 유저' 의 MAX 가 달라질 수 있는 변형 문제에서 틀린다.max_streak_days DESC 만 쓰면 같은 값들 사이 순서가 실행마다 바뀐다.“연속 출석일수”, “N일 연속 접속”, “연속 결제 개월수” 전부 같은 패턴이다. 월 단위면 일련번호를 TIMESTAMPDIFF(MONTH, 기준월, 그달) 로 바꾼다. “현재 진행 중인 연속일수”면 마지막 구간만 (MAX(order_date) = 오늘 인 구간) 남긴다.