한 번의 실행 축으로 보면 역할이 분리됩니다.
행 필터 → 그룹화 → 그룹 필터
step 1
원본 행 준비
FROM으로 집계 대상 행을 모읍니다.
예: 주문 12행
step 2
WHERE로 먼저 거르기
그룹화 전에 개별 행을 제외합니다.
예: 취소 주문 제외 → 7행
step 3
GROUP BY로 묶기
같은 값끼리 한 그룹이 되고, NULL도 하나의 그룹 키가 됩니다.
예: 부서별 3그룹
step 4
HAVING + SELECT
집계가 끝난 그룹만 다시 걸러서 결과 행으로 꺼냅니다.
예: COUNT(*) > 1 인 2그룹
WHERE는 아직 그룹이 없을 때 쓰는 조건입니다. 그래서 집계값을 직접 비교하지 않습니다.
HAVING은 그룹이 만들어진 뒤의 조건입니다. 소계, 평균, 건수 같은 집계 결과를 기준으로 고릅니다.
그룹 결과 한 행의 규칙
모호하지 않게 읽기
SELECT의 비집계 컬럼은 GROUP BY에 포함
그룹 결과 한 행이 어떤 값을 대표하는지 분명해야 합니다.
GROUP BY만으로 정렬되지는 않음
표시 순서가 필요하면 마지막에 ORDER BY를 따로 적어야 합니다.
확장 집계는 같은 규칙 위에 붙음
ROLLUP은 소계, CUBE는 모든 조합, GROUPING SETS는 필요한 조합만 계산합니다.
ROLLUP: 소계 + 총계
CUBE: 가능한 조합 전체
GROUPING SETS: 필요한 조합만
집계 함수가 NULL을 읽는 방식
결과 해석의 기준COUNT(*)
NULL 여부와 상관없이 행 수 전체를 셉니다.
COUNT(col)
해당 컬럼이 NULL인 행은 제외합니다.
SUM / AVG
NULL을 건너뜁니다. 전부 NULL이면 결과는 0이 아니라 NULL입니다.
MAX / MIN
NULL을 무시한 뒤 남은 값끼리 비교합니다.