오라클 SQL에서 GROUP BY 절을 사용하여 그룹별 건수나 합계를 얻을 수 있다. 그룹별 집계된 결과 중 원하는 조건의 결과만 필터링하기 위해서는 HAVING 절을 사용하여 필터 조건을 사용할 수 있다.
HAVING 절과 WHERE 절의 다른 점은 HAVING 절은 GROUP BY 절과 함께 사용해야 하며 집계 함수를 사용하여 조건절을 작성하거나 GROUP BY 컬럼만 조건절에 사용할 수 있다.
SELECT job
, COUNT(*) cnt
FROM emp
WHERE deptno IN ('10', '20', '30')
GROUP BY job
HAVING COUNT(*) > 2
위의 쿼리문은 직군(job) 별 직원 수가 3명 이상일 경우만 조회하는 예제이다.
HAVING 절에는 COUNT, SUM, AVG, MAX, MIN 등 집계함수를 사용하여 조건을 부여할 수 있다.
SELECT job
, COUNT(*) cnt
, SUM(sal) sal
FROM emp
WHERE deptno IN ('10', '20', '30')
GROUP BY job
HAVING COUNT(*) > 2 AND SUM(sal) > 5000
AND, OR 를 사용하여 여러 조건을 동시에 부여할 수 있다.
SELECT job
, deptno
, COUNT(*) cnt
FROM emp
WHERE deptno IN ('10', '20', '30')
GROUP BY job, deptno
HAVING deptno = '20'
GROUP BY에 사용된 컬럼(job, deptno)은 집계함수 없이 조건으로 사용할 수 있다.
GROUP BY에 사용되지 않은 컬럼을 조건으로 사용하면 아래의 오류가 발생한다.
- ORA-00979: GROUP BY 표현식이 아닙니다
SELECT job
, deptno
, COUNT(*) cnt
FROM emp
WHERE deptno IN ('10', '20', '30')
GROUP BY job, deptno
HAVING (deptno = '20' AND COUNT(*) > 1)
OR (deptno = '30' AND COUNT(*) > 2)
여러 조건을 묶어서 다양한 조건을 부여할 수 있다.
SELECT job
, COUNT(*) cnt
FROM emp
WHERE deptno IN ('10', '20', '30')
GROUP BY job
HAVING COUNT(*) = COUNT(DISTINCT deptno)
집계함수를 서로 비교할 수 있다.
집계함수에 사용되는 컬럼(depno)은 GROUP BY 절에 사용되지 않은 컬럼도 사용가능 하다.