21. SQL - 반복해서 틀리는 것들 (#2) consecutive days

Jason·2026년 1월 15일

SQL

목록 보기
20/47

[SQL 코테] 연속 날짜 그룹핑 내가 틀린 것들 정리 🔥

🚨 핵심 실수 포인트 (시험 전 필독!)

1. DATE_SUB는 윈도우 함수 아님! OVER() 안 붙어!
2. DATE_SUB(날짜, INTERVAL rn DAY) ← 문법 외우기
3. grp는 그룹 키일 뿐! 연속 일수 = COUNT(*)
4. GROUP BY는 grp로! (streak_days는 결과값이라 안 됨)

📝 문제: 유저별 연속 로그인 구간 찾기

테이블 구조

logins 테이블
id  | user_id | login_date
----|---------|------------
1   | 301     | 2024-03-01
2   | 301     | 2024-03-02
3   | 301     | 2024-03-03
4   | 301     | 2024-03-07
5   | 301     | 2024-03-08
6   | 302     | 2024-03-01
7   | 302     | 2024-03-03

✅ 정답 쿼리

WITH cte_rn AS ( 
  SELECT 
    user_id, login_date, 
    ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY login_date) AS rn 
  FROM logins 
), 
cte_grp AS ( 
  SELECT 
    user_id, login_date, rn, 
    DATE_SUB(login_date, INTERVAL rn DAY) AS grp 
  FROM cte_rn 
) 
SELECT 
  user_id, 
  MIN(login_date) AS start_date, 
  MAX(login_date) AS end_date, 
  COUNT(*) AS streak_days
FROM cte_grp 
GROUP BY user_id, grp
ORDER BY user_id, start_date;

❌ 내가 틀린 것들

1. DATE_SUB는 윈도우 함수가 아니야!

-- ❌ OVER() 붙이면 안 돼!
DATE_SUB((login_date, rn) OVER(PARTITION BY user_id ORDER BY login_date))

-- ✅ 그냥 일반 함수
DATE_SUB(login_date, INTERVAL rn DAY)

기억: DATE_SUB, DATEDIFF는 일반 함수! OVER() 안 붙어!


2. DATE_SUB 문법 구조

DATE_SUB(날짜, INTERVAL 숫자 단위)
부분의미
DATE_SUB(A, B)A에서 B를 빼라
login_date기준 날짜
INTERVAL rn DAYrn일 만큼

예시:

DATE_SUB('2024-03-03', INTERVAL 3 DAY) = '2024-02-29'

3. grp vs COUNT(*) 구분!

-- ❌ grp는 그룹 키일 뿐, 연속 일수 아님
grp AS streak_days

-- ✅ 행 갯수 = 연속 일수
COUNT(*) AS streak_days

grp 값 확인:

user_id | login_date | rn | grp
--------|------------|----|-----------
301     | 03-01      | 1  | 02-29  ←┐
301     | 03-02      | 2  | 02-29  ←┼ 같은 값 = 연속!
301     | 03-03      | 3  | 02-29  ←┘
301     | 03-07      | 4  | 03-03  ←┐
301     | 03-08      | 5  | 03-03  ←┘

grp = '02-29'는 "이 행들이 같은 그룹이다"라는 표식일 뿐! 날짜 자체는 의미 없어!


4. GROUP BY는 grp로!

-- ❌ streak_days는 SELECT에서 만든 결과값
GROUP BY user_id, streak_days

-- ✅ grp로 묶어야 연속 구간끼리 그룹됨
GROUP BY user_id, grp

흐름:

1. grp로 GROUP BY → 연속 구간끼리 묶임
2. 묶인 그룹 안에서 COUNT(*) → streak_days 계산됨

💡 DATE_SUB vs DATEDIFF 비교

함수하는 일결과 타입
DATE_SUB(날짜, INTERVAL n DAY)날짜 - n일DATE
DATEDIFF(날짜1, 날짜2)날짜 차이 계산INT (정수)
DATE_SUB('2024-03-03', INTERVAL 3 DAY)'2024-02-29' (날짜)
DATEDIFF('2024-03-03', '2024-03-01')2 (숫자)

🎯 체크리스트

  • DATE_SUB에 OVER() 붙이지 않기
  • DATE_SUB(날짜, INTERVAL rn DAY) 문법
  • 연속 일수 = COUNT(*) (grp 아님!)
  • GROUP BY는 grp로

채널톡 DA 인턴 코테 준비 중 정리한 내용입니다 🚀

profile
Data Analyst | Thoughts Become Things. 할 수 있다고 생각하면 할 수 있다. 할 수 없다고 생각하면 할 수 없다. | www.linkedin.com/in/명수-제-7ab843200

0개의 댓글