데이터베이스/Oracle SQL

오라클 SQL과 PL/SQL ( GROUP BY / HAVING )

동띠기 2021. 7. 29. 21:48

GROUP BY / 특정 조건으로 세부적인 그룹화 하기


특정 조건을 주고 해당 조건에 맞는 결과들을 모아서 조금 더 구체적인 결과를 만드는건 GROUP BY를 사용합니다.

SELECT DEPTNO, AVG(NVL(SAL, 0)) "AVG"
FROM EMP
GROUP BY DEPTNO;

위 예제는 EMP 테이블을 조회하여 부서별로 평균 급여 금액을 구하는 예제입니다.
위 처럼 세부적인 그루핑을 하고싶으면 GROUP BY절에 해당컬럼명을 적으면 됩니다.
위 내용은 전체의 평균 급여를 구하는 것이 아니라 각 학과별로 평균 급여를 조회하는 것이므로 대상 데이터를 전부 읽은 후 GROUP BY절에 적혀있는 컬럼인 DEPTNO로 분류합니다.
그 후 DEPTNO별로 급여를 계산해서 결과를 출력 했습니다.
GROUP BY를 어려워 하는사람이 있는데, 원리는 GROUP BY 뒤에 오는 컬럼 값을 기준으로 먼저 모아놓고 SELECT절에 적혀있는 그룹함수를 적용하게 됩니다.
만약 그룹핑할 조건이 여러개일 경우 GROUP BY절에 이어서 적으면 됩니다.

 

SELECT DEPTNO, JOB, AVG(NVL(SAL, 0)) "AVG_SAL"
FROM EMP
GROUP BY DEPTNO , JOB 
ORDER BY DEPTNO , JOB

부서별로 먼저 그루핑을 하고 같은 학과일 경우 직급별로 한번더 분류해서 평균 급여를 출력한 것입니다.

**GROUP BY절을 사용할 경우 주의사항**

1. SELECT절에 사용된 그룹 함수 이외의 컬럼이나 표현식은 반드시 GROUP BY절에 사용되어야 합니다.
2. GROUP BY절에는 반드시 컬럼명이 사용되어야 하며 컬럼 ALIAS(별명)는 사용하면 안됩니다.

 

HAVING / 그룹핑한 조건으로 검색하기


조건을 주고 검색을 할 떄 WHERE절을 사용하는 것을 아실겁니다. 

그러나 모든 조건을 WHERE로 처리하는것은 아닙니다.
아래 예제를 보겠습니다.

 

EMP테이블에서 평균 급여가 2000이상인 부서의 부서번호와 평균 급여를 구하세요.

SELECT DEPTNOP, AVG(NVL(SAL, 0))
FROM EMP
WHERE AVG(NVL(SAL, 0)) > 2000

WHERE절에 평균 급여를 뜻하는 WHERE AVG(NVL(SAL, 0)) > 2000라고 썻는데 에러가 발생합니다.
이유는 에러 메시지 처럼 WHERE 절은 그룹 함수를 비교 조건으로 쓸 수가 없습니다.
만약 그룹함수를 조건으로 사용하고 싶을 경우에는 WHERE 대신에 HAVING를 사용합니다.

 

SELECT DEPTNO, AVG(NVL(SAL, 0))
FROM EMP
GROUP BY DEPTNO
HAVING AVG(NVL(SAL, 0)) > 2000

위와 같이 그룹 함수를 비교 조건으로 사용하려면 4번줄 처럼 반드시 HAVING절을 사용해야 합니다.
HAVING 절의 위치는 GROUP BY 절 이전이든 이후든 상관없습니다. 
그리고 그룹함수를 사용하는 SQL이라 하더라도 조건이 그룹 함수가 아닌 일반 조건일 경우 WHERE을 사용하면 됩니다.

728x90