2.1.7 Group by, Having 절
집계 함수
- 여러 행들의 그룹이 모여서 그룹 당 하나의 결과를 알려주는 다중행 함수 중 하나
- 그룹 당 하나의 결과를 돌려줌
- GROUP BY는 행들을 소그룹화
- SELECT, HAVING, ORDER BY 절에 사용
- WHERE 절에 사용하지 않음
집계함수명 ([DISTINCT/ALL] 칼럼이나 표현식)

- COUNT(*) 는 NULL 값을 포함한 행의 수를 출력함
- COUNT(표현식)은 NULL 값 제외한 행의 수를 출력
GROUP BY
- WHERE 통해 조건에 맞는 데이터 조회 후 2차 가공 정보 필요한 경우 GROUP BY 사용
- FROM, WHERE 뒤에 옴
SELECT [DISTINCT] 칼럼명 [ALIAS명]
FROM 테이블명
[WHERE 조건식]
[GROUP BY 칼럼이나 표현식]
[HAVING 그룹조건식];
GROUP BY 절과 HAVING 절의 특성
- GROUP BY 절을 통해 소그룹별 기준을 정한 후, SELECT 절에 집계함수를 사용
- 집계 함수의 통계 정보는 NULL 값을 가진 행을 제외하고 수행
- GROUP BY 절에서 SELECT 절과는 달리 ALIAS(별명)을 사용 불가
- 집계함수는 WHERE 절에는 올 수 없음 (집계함수를 사용할 수 있는 GROUP BY 절보다 WHERE 절이 먼저 수행되는 특성 상)
- WHERE 절은 전체 데이터를 GROUP으로 나누기 전에 행들을 미리 제거
- HAVING 절은 GROUP BY 절의 기준 항목이나 소그룹의 집계 함수를 이용한 조건을 표시
- GROUP BY 절에 의한 소그룹별로 만들어진 집계 데이터 중, HAVING 절에서 제한 조건을 두어 조건을 만족하는 내용만 출력
- HAVING 절은 일반적으로 GROUP BY 절 뒤에 위치
- GROUP BY, HAVING 절은 ORDER BY 절 없이 정렬 불가
HAVING
- 예제) K-리그 선수들의 포지션별 평균키를 구하는데, 평균키가 180 센티미터 이상인 정보만 표시
SELECT POSITON 포지션, ROUND(AVG(HEIGHT), 2) 평균키
FROM PLAYER
WHERE AVG(HEIGHT) >= 180
GROUP BY POSITON
- 위 쿼리는 잘못된 쿼리임
- WHERE 뒤에 집계함수 AVG의 사용이 불가능
SELECT POSITON 포지션, ROUND(AVG(HEIGHT), 2) 평균키
FROM PLAYER
GROUP BY POSITON
HAVING AVG(HEIGHT) > 180;
- WHERE 뒤에 집계함수 AVG의 사용이 불가능하고, GROUP BY/HAVING 절로 표현 가능함.
- WHERE 조건 변경은 대상 데이터의 개수가 변경되므로 결과 데이터 값이 변경 가능하지만, HAVING절의 조건 변경은 결과 데이터 변경은 없고 출력되는 레코드의 갯수만 변경될 수 있다.
CASE 표현을 활용한 월별 데이터 집계
- 제 1정규화로 인해 반복되는 칼럼의 경우 구분 칼럼을 두고 여러 개의 레코드로 만들어진 집합을 정해진 칼럼 수만큼 확장해서 집계 보고서를 만드는 유용한 기법
집계함수와 NULL 처리
- 빈 칸을 NULL이 아닌 ZERO로 표현하기 위해 NVL/ISNULL 함수를 사용하는 경우, 다중 행 함수를 사용하는 경우에 오히려 불필요한 부하가 발생되므로 굳이 NVL 함수를 다중 행 함수 안에 사용할 필요가 없음
- 같은 결과를 얻을 수 있다면 가능한 ELSE 절의 상수 값을 지정하지 않거나 ELSE 절을 작성하지 않도록 하는 경우 NULL이 디폴트 값으로 할당 됨.
- 불필요하게 NVL / ISNULL 함수를 사용해 0으로 변환시켜 데이터 건수만큼의 연산이 일어나게 하는 것은 시스템 자원을 낭비시키는 일임.