SQL 면접 문제집
샘플 3문제전체 30문제
실제 데이터 분석가/엔지니어 면접에서 출제되는 SQL 문제들입니다. 각 문제는 문제 → 힌트 → 정답 → 해설 → 면접 포인트 순서로 구성되어 있습니다.
🟢 샘플 문제 (3/30)
문제 1. 기본 집계
초급
[문제] 2024년 1월에 완료된 주문의 총 매출과 평균 주문금액을 구하세요.
테이블: src_orders, src_order_items
💡 힌트 보기
JOIN으로 주문과 주문상품을 연결WHERE로 날짜와 상태 필터링SUM,AVG집계함수 사용
✅ 정답 코드
SELECT
COUNT(DISTINCT o.order_id) AS total_orders,
SUM(oi.sale_price) AS total_revenue,
AVG(oi.sale_price) AS avg_item_price,
SUM(oi.sale_price) / COUNT(DISTINCT o.order_id) AS avg_order_value
FROM src_orders o
JOIN src_order_items oi ON o.order_id = oi.order_id
WHERE o.created_at >= '2024-01-01'
AND o.created_at < '2024-02-01'
AND o.status = 'Complete';📖 상세 해설
핵심 포인트:
COUNT(DISTINCT o.order_id): 중복 제거하여 실제 주문 수 계산- 날짜 필터링:
>= AND <패턴이BETWEEN보다 명확 - 평균 주문금액: 아이템 평균이 아닌 주문당 평균 계산
자주 하는 실수:
COUNT(*)사용 시 주문상품 수가 됨 (주문 수 X)BETWEEN사용 시 경계값 포함 여부 혼동
면접관 포인트:
“왜 DISTINCT를 사용했나요?” → 1:N 관계에서 중복 방지 설명
문제 2. GROUP BY + HAVING
초급
[문제] 10건 이상 주문한 고객 중, 총 구매금액 상위 5명을 구하세요.
💡 힌트 보기
GROUP BY로 고객별 집계HAVING으로 10건 이상 필터링ORDER BY+LIMIT으로 상위 5명
✅ 정답 코드
SELECT
o.user_id,
COUNT(DISTINCT o.order_id) AS order_count,
SUM(oi.sale_price) AS total_spent
FROM src_orders o
JOIN src_order_items oi ON o.order_id = oi.order_id
WHERE o.status = 'Complete'
GROUP BY o.user_id
HAVING COUNT(DISTINCT o.order_id) >= 10
ORDER BY total_spent DESC
LIMIT 5;📖 상세 해설
WHERE vs HAVING:
WHERE: 그룹화 전 행 단위 필터링HAVING: 그룹화 후 그룹 단위 필터링
-- WHERE: 개별 행 필터 (그룹화 전)
WHERE status = 'Complete'
-- HAVING: 집계 결과 필터 (그룹화 후)
HAVING COUNT(*) >= 10실행 순서:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT면접관 포인트:
“HAVING 대신 서브쿼리로 풀 수도 있나요?” → 성능 차이 논의
문제 3. LEFT JOIN 이해
초급
[문제] 한 번도 주문하지 않은 고객 목록을 구하세요.
💡 힌트 보기
LEFT JOIN사용- 매칭되지 않으면
NULL이 되는 성질 활용
✅ 정답 코드
-- 방법 1: LEFT JOIN + IS NULL
SELECT u.user_id, u.email, u.created_at
FROM src_users u
LEFT JOIN src_orders o ON u.user_id = o.user_id
WHERE o.order_id IS NULL;
-- 방법 2: NOT EXISTS (더 효율적인 경우 있음)
SELECT user_id, email, created_at
FROM src_users u
WHERE NOT EXISTS (
SELECT 1
FROM src_orders o
WHERE o.user_id = u.user_id
);
-- 방법 3: NOT IN (NULL 주의)
SELECT user_id, email, created_at
FROM src_users
WHERE user_id NOT IN (
SELECT DISTINCT user_id
FROM src_orders
WHERE user_id IS NOT NULL
);📖 상세 해설
LEFT JOIN의 동작:
Users Orders Result (LEFT JOIN)
------ ------ -----------------
user_id=1 user_id=1 → user_id=1, order_id=100
user_id=2 (없음) → user_id=2, order_id=NULL ← 이것을 필터링
user_id=3 user_id=3 → user_id=3, order_id=101세 가지 방법 비교:
| 방법 | 장점 | 단점 |
|---|---|---|
| LEFT JOIN + NULL | 직관적 | 대용량에서 느릴 수 있음 |
| NOT EXISTS | 효율적 | 문법이 복잡 |
| NOT IN | 간결 | NULL 처리 주의 필요 |
면접관 포인트:
“NOT IN에서 NULL이 있으면 어떻게 되나요?” → 전체 결과가 빈 집합
🔒 프리미엄 문제 (27문제)
전체 30문제 구성
| 난이도 | 문제 수 | 주요 토픽 |
|---|---|---|
| 🟢 초급 | 10문제 | JOIN, GROUP BY, 날짜함수, CASE WHEN |
| 🟡 중급 | 10문제 | 윈도우 함수, LAG/LEAD, 누적합, CTE |
| 🔴 고급 | 10문제 | 코호트 분석, 퍼널, 세션화, 피벗 |
프리미엄에서 배우는 내용
- ✅ 윈도우 함수 마스터: ROW_NUMBER, RANK, LAG, LEAD, SUM OVER
- ✅ 코호트 리텐션 분석: 실제 기업에서 사용하는 SQL
- ✅ 퍼널 분석: 전환율 계산 쿼리
- ✅ 세션화 (Sessionization): 30분 간격 세션 ID 부여
- ✅ Anti-Join 패턴: 이탈 고객 찾기
- ✅ 면접관이 기대하는 답변 포인트
🎯 전체 30문제 + 해설 구매하기
SQL + Pandas + 통계 + 케이스 스터디 번들 할인
📝 무료로 더 연습하기
면접 준비가 더 필요하다면, Cookbook의 개념 섹션을 복습하세요:
Last updated on