Programming/SQL

[Oracle] GROUP BY / HAVING절 / 집합 연산자 SET OPERATOR (UNION/ALL/INTERSECT/MINUS)

Jayna. 2024. 2. 15. 17:06
728x90

GROUP BY절

그룹을 묶어줄 기준을 제시할 수 있는 구문

여러개 값들을 그룹별로 나눠서 처리할 목적으로 사용한다.

-- 전체 사원의 총 급여 합
SELECT SUM(SALARY)
  FROM EMPLOYEE;
--> 현재 조회된 전체사원들을 하나의 그룹으로 묶어서 총합을 구한 결과

-- 각 부서별 총 급여 합
SELECT DEPT_CODE, SUM(SALARY)
  FROM EMPLOYEE
 GROUP BY DEPT_CODE;
 
-- 전체 사원 수
SELECT COUNT(*)
  FROM EMPLOYEE;

-- 각 부서별 사원 수
SELECT DEPT_CODE, COUNT(*)
  FROM EMPLOYEE
 GROUP BY DEPT_CODE;
 
-- 각 부서별 총 급여 합을 부서별 오름차순 정렬해서 조회        <실행순서>
SELECT DEPT_CODE, SUM(SALARY)                             -- 3. SELECT절
  FROM EMPLOYEE                                           -- 1. FROM절
 GROUP BY DEPT_CODE                                       -- 2. GROUP절
 ORDER BY DEPT_CODE;                                      -- 4. ORDER BY절
728x90

HAVING절

그룹에 대한 조건을 제시하고자 할 때 사용되는 구문

(대부분의 경우 그룹함수를 가지고 조건 제시)

GROUP BY에서는 WHERE절을 쓸 수 없기 때문에 HAVING절을 사용하면 된다.

-- 부서별 평균급여 300만원 이상인 부서들만 조회
SELECT DEPT_CODE, ROUND(AVG(SALARY))
  FROM EMPLOYEE
--WHERE AVG(SALARY) >= 3000000       -- GROUP BY 에선 WHERE 절 사용할 수 없음
 GROUP BY DEPT_CODE;
 
 SELECT DEPT_CODE, ROUND(AVG(SALARY))
   FROM EMPLOYEE
  GROUP BY DEPT_CODE
  HAVING AVG(SALARY) >= 3000000;
  
  -- 각 직급 별 총 급여 합이 1000만원 이상인 직급코드, 급여 합을 조회
  SELECT JOB_CODE, SUM(SALARY)
    FROM EMPLOYEE
   GROUP BY JOB_CODE >= 10000000;
   
 -- 각 부서별 보너스를 받는 사원이 없는 부서만을 조회
 SELECT DEPT_CODE
   FROM EMPLOYEE
  GROUP BY DEPT_CODE
 HAVING COUNT(BONUS) = 0;

 

실행 순서 

5: SELECT 

1: FROM 

2: WHERE 

3: GROUP BY 

4. HAVING 

6: ORDER BY

 

집합 연산자 SET OPERATOR

여러 개의 쿼리문을 가지고 하나의 쿼리문으로 만드는 연산자

 

1) UNION (중복값은 하나만 보여줌) 

--부서코드가 D5이거나 또는 급여가 300만원 초과인 사원들 조회
SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE DEPT_CODE = 'D5'
 UNION
SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE SALARY > 3000000;
 
 -- => OR 연산자로 대체 가능
 SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE DEPT_CODE = 'D5' OR SALARY > 3000000;

 

2) UNION ALL (중복을 모두 보여준다)

SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE DEPT_CODE = 'D5'
 UNION ALL
SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE SALARY > 3000000;

 

3) INTERSECT 교집합

SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE DEPT_CODE = 'D5'
 INTERSECT
SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE SALARY > 3000000;
 
 -- => AND 연산자로 대체 가능
 SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE DEPT_CODE = 'D5'
   AND SALARY > 3000000;

 

4) MINUS 차집합(선행 쿼리문 결과값 - 후행 쿼리문 결과값)

-- 부서코드가 D5인 사원들 중 급여가 300만원 초과인 사원들을 제외하고 조회
SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE DEPT_CODE = 'D5'
 MINUS
SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE SALARY > 3000000;
 
 -- => AND 연산자로 대체 가능
 SELECT EMP_ID 사번
     , EMP_NAME 사원명
     , DEPT_CODE 부서코드
     , SALARY 급여
  FROM EMPLOYEE
 WHERE DEPT_CODE = 'D5'
   AND SALARY <= 3000000;

 

728x90