
1. FROM절 서브쿼리 = SELECT 결과를 임시 테이블처럼 사용 2. 서브쿼리에는 반드시 별명(alias) 붙여야 함! 3. WITH문 = 서브쿼리를 미리 정의해두는 것 (가독성 좋음!) 4. WITH는 "재료 준비", JOIN은 "요리하기" - 둘 다 필요!
SELECT 결과를 임시 테이블처럼 사용하는 것!
-- 일반 JOIN
FROM users u
JOIN orders o ON u.user_id = o.user_id
-- 서브쿼리 JOIN (orders 자리에 SELECT 결과가 들어감)
FROM users u
JOIN (SELECT ...) fo ON u.user_id = fo.user_id
-- ❌ 별명 없으면 에러!
JOIN (SELECT user_id, MIN(order_date) FROM orders GROUP BY user_id)
ON u.user_id = ???.user_id -- 뭐라고 부르지?
-- ✅ 별명 붙여줘야 함!
JOIN (SELECT user_id, MIN(order_date) AS first_order_date
FROM orders GROUP BY user_id) fo ← "fo"라는 별명!
ON u.user_id = fo.user_id
같은 쿼리, 다른 표현:
SELECT
DATE_FORMAT(u.signup_date, '%Y-%m') AS cohort_month,
ROUND(AVG(DATEDIFF(fo.first_order_date, u.signup_date)), 1) AS avg_days
FROM users u
JOIN (
SELECT user_id, MIN(order_date) AS first_order_date
FROM orders
GROUP BY user_id
) fo ON u.user_id = fo.user_id
GROUP BY cohort_month
ORDER BY cohort_month;
WITH fo AS (
SELECT user_id, MIN(order_date) AS first_order_date
FROM orders
GROUP BY user_id
)
SELECT
DATE_FORMAT(u.signup_date, '%Y-%m') AS cohort_month,
ROUND(AVG(DATEDIFF(fo.first_order_date, u.signup_date)), 1) AS avg_days
FROM users u
JOIN fo ON u.user_id = fo.user_id
GROUP BY cohort_month
ORDER BY cohort_month;
WITH는 "재료 준비"일 뿐, JOIN은 따로 해줘야 해!
-- ❌ JOIN 빠뜨리면 안 돼!
WITH fo AS (SELECT ...)
SELECT ...
FROM users u
GROUP BY ... -- fo 어디 갔어?
-- ✅ JOIN으로 연결 필수!
WITH fo AS (SELECT ...)
SELECT ...
FROM users u
JOIN fo ON u.user_id = fo.user_id ← 이거 필수!
GROUP BY ...
비유:
재료 준비했다고 자동으로 요리되는 게 아니야!
| 방식 | 가독성 | 추천 상황 |
|---|---|---|
| 서브쿼리 | 보통 | 간단한 쿼리 |
| WITH (CTE) | 좋음 ✅ | 복잡한 쿼리 |
면접 팁: 둘 다 쓸 줄 알면 좋고, 복잡한 쿼리는 WITH 쓰는 게 인상 좋아!
채널톡 DA 인턴 코테 준비 중 정리한 내용입니다 🚀
