HAVING절은 보통 GROUP BY에서 해당 집계함수에 대한 조건을 추가할때 사용한다.
그러나 GROUP BY없이도 단독으로 HAVING절을 사용할 수 있는 경우가 있다.
해당 table column 구성에서, 각 column별 소그룹으로 묶지 않고 테이블 전체를 동일한 그룹으로 보고 group by하고자 할때 단독으로 HAVING절을 사용할 수 있다.
이렇게만 보면 잘 이해가 안가는데, 아래 예시를 살펴본다.
WITH A as(
SELECT 'pencil' as item, 2 as cnt
FROM DUAL
UNION ALL
SELECT 'knife' as item, 5 as cnt
FROM DUAL
)
위 SQL문장으로 임의의 테이블을 생성하면, 아래와 같은 구성의 임시 테이블이 생성된다.
이 테이블을 바탕으로 아래의 단독 HAVING 조건절을 사용한다고 해보자.
WITH A as (
SELECT ~~ (생략)
)
SELECT AVG(CNT)
FROM A
HAVING AVG(CNT) < 10
이럴 경우 결과가 3.5이다.
즉, pencil이나 knife 등의 소그룹으로 나누지 않고 테이블 전체를 동일한 그룹에 있는 항목들로 간주하고, 모든 데이터들에 대해 집계함수를 적용한다.
만약 HAVING 조건에서 AVG(CNT) < 3으로 한다면, 테이블 전체 데이터의 AVG를 하는데 이 값이 3.5이고 조건절을 만족하지 않으므로 출력값은 존재하지 않는다.
WITH A as (
SELECT ~~ (생략)
)
SELECT SUM(CNT)
FROM A
HAVING SUM(CNT) < 10
이럴 경우, 전체 데이터를 하나의 그룹화하여 그대로 집계함수를 적용하여 결과값이 7이 나온다.
HAVING 조건절에서 SUM(CNT) < 5라는 조건을 넣게되면 해당 결과는 없다(NULL).
WITH A as (
~~
)
SELECT item, cnt
FROM A
HAVING item, SUM(CNT)
FROM A
HAVING SUM(CNT) < 10
위 SQL문은 잘못된 구성이다.
단독으로 HAVING절을 사용하여 테이블 전체를 하나의 그룹화한 항목으로 간주하였으므로, 테이블내에서 소그룹화할 수 는 없다.
즉, itme별로 소그룹화할 수 없으므로 해당 SQL문은 "단일 그룹의 그룹 함수가 아닙니다"라는 오류를 발생한다.
HAVING 조건절 단독 사용 관련 - https://ggmouse.tistory.com/447