결제없음 뒤로, total_amount DESC, user_id ASC / LIMIT 20전교생 명단에 성적을 붙이는데, 시험 안 본 애도 명단에 남아야 한다. 점수 칸은 0 으로, 시험 날짜 칸은 빈칸으로.
더할 게 하나도 없을 때 뭐가 나오나 — 이걸 알아야 풀린다.
| 함수 | 아무것도 없을 때 |
|---|---|
| COUNT(*) · COUNT(칸) | 0 |
| SUM · AVG · MAX · MIN | NULL (0 이 아니다!) |
COUNT — 결제가 없으면 자동으로 0 이 된다.COALESCE(SUM(금액), 0) — SUM 밖에 씌운다.SUM 은 더할 게 없으면 0 이 아니라 NULL 이다. 그래서 COALESCE(…, 0) 이 필요하다. 이것 때문에 금액 칸이 빈칸으로 나오는 실수가 가장 흔하다.ORDER BY (마지막결제일 IS NULL), 금액 DESC, user_id ASC — IS NULL 은 0 또는 1 이라서, 결제 있는 사람(0)이 먼저 온다.LIMIT 20 빼먹지 마라. 안 쓰면 3,000줄이 다 나온다.묻는 것 · LEFT JOIN 후 NULL 을 어떻게 다루는가. 그리고 NULL 정렬.
COUNT(p.user_id) — NULL 을 안 세므로 0 이 된다.COALESCE(SUM(...), 0) — SUM 은 대상이 없으면 NULL 을 반환한다.SELECT u.user_id, u.channel,
COUNT(p.user_id) AS pay_count,
COALESCE(SUM(p.amount), 0) AS total_amount,
MAX(p.paid_date) AS last_paid
FROM users u
LEFT JOIN payments p ON p.user_id = u.user_id
GROUP BY u.user_id, u.channel
ORDER BY (MAX(p.paid_date) IS NULL), COALESCE(SUM(p.amount),0) DESC, u.user_id
LIMIT 20;COUNT(*) 를 쓰면 결제 없는 유저도 1 이 된다. LEFT JOIN 으로 행은 하나 생기기 때문. COUNT(p.user_id) 여야 0.SUM 은 대상 행이 없으면 0 이 아니라 NULL. COALESCE 로 감싼다.NULLS LAST 가 없다. ORDER BY (컬럼 IS NULL), 컬럼 로 쓴다. 조건식이 0/1 이 되어 NULL 이 뒤로 간다.COALESCE(total, '없음') 처럼 문자 기본값을 넣으면 컬럼 전체가 문자열이 되어 정렬이 사전순으로 깨진다.“주문 없는 고객 포함 요약”, “미거래 종목 포함” 전부 동일.