💁♀️ 그룹화(Grouping)란,
데이터를 그룹화하는 것, 즉 데이터를 집계하는 것으로써 단 한 개의 결과값만 산출하는 그룹함수를 이용하여 여러 개의 결과값을 산출하기 위해 사용
📍 작성하는 절들의 순서 및 작동되는 우선 순위
FROM이 가장 먼저 작동 후, ORDER BY가 가장 마지막으로 실행됨
[ 5 ] SELECT 컬럼명 AS 별칭, 계산식, 함수식
[ 1 ] FROM 참조할 테이블명
[ 2 ] WHERE 컬럼명 or 함수식 비교 연산자 비교값
[ 3 ] GROUP BY 그룹을 묶을 컬럼명
[ 4 ] HAVING 그룹함수식 비교연산자 비교값
[ 6 ] ORDER BY 컬럼명 or 별칭 or 컬럼순법 정렬방식 [NULL FIRST or LAST]
ORDER BY 컬럼명 or 별칭 or 컬럼순번 정렬방식 NULLS FIRST or LAST
💁♀️ ORDER BY절이란,
SELECT한 컬럼에 대해 정렬을 할 때 작성하는 구문
- SELECT 구문의 가장 마지막에 작성하며, 실행순서도 가장 마지막에 수행
GROUP BY 컬럼명 or 함수식, ...
💁♀️ GROUP BY절이란,
같은 값들이 여러 개 기록된 컬럼을 가지고 같은 값들을 하나의 그룹으로 묶는 절
- 그룹함수를 이용하여 여러 개의 결과값을 산출하기 위해서 그룹함수가 적용될 그룹의 기준을 GROUP BY절에 기술하여 사용
- 그룹으로 묶은 값에 대해서 SELECT 절에서 그룹 함수의 사용을 가능하게 함
SELECT
COUNT(*) >>> NULL을 포함한 전체 행 갯수 리턴
, DEPT_CODE
FROM EMPLOYEE
GROUP BY DEPT_CODE;
>>> DEPT_CODE로 그룹화하면 부서당 몇명의 인원이 있는지 카운팅 가능
>>> (부서코드가 같은 것끼리 그룹화 후, 그것의 갯수를 COUNT)
>>> 그룹화 하지 않았을 경우, 그룹 함수인 COUNT 사용 불가
SELECT
DEPT_CODE 부서
, SUM(SALARY) 합계
, ROUND(AVG(SALARY)) 평균
, COUNT(*) 인원수
FROM EMPLOYEE
GROUP BY DEPT_CODE
ORDER BY DEPT_CODE;
/* ORDER BY 부서; */
/* ORDER BY 1; */ >>> 부서를 의미
/* ORDER BY 1 DESC; */ >>> 거꾸로(내림차순)
/* ORDER BY 1 DESC NULLS LAST; */ >>> 내림차순 및 NULL을 가장 마지막으로
📌 Ref.
ORDER BY 컬럼명 or 별칭 or 컬럼순번 정렬방식 NULLS FIRST or LAST
SELECT
JOB_CODE
, COUNT(BONUS) >>> NULL값을 가진 행 제외하고 조회
FROM EMPLOYEE
GROUP BY JOB_CODE
ORDER BY JOB_CODE;
SELECT
JOB_CODE
, COUNT(BONUS)
FROM EMPLOYEE
WHERE BONUS IS NOT NULL >>> WHERE절(조건)로 그룹화 전 미리 안받는 사람을 빼둠
GROUP BY JOB_CODE
ORDER BY JOB_CODE;
SELECT
DEPT_CODE
, JOB_CODE
, SUM(SALARY)
, COUNT(*) >>> 해당 부서에서 해당 직급을 가지고 있는 사람들을 COUNT (중복 그룹)
FROM EMPLOYEE
GROUP BY DEPT_CODE
, JOB_CODE
ORDER BY 1;
SELECT
DECODE(SUBSTR(EMP_NO, 8, 1), '1', '남', '2', '여') 성별
, ROUND(AVG(SALARY)) 평균
, SUM(SALARY) 합계
, COUNT(*) 인원수
FROM EMPLOYEE
GROUP BY DECODE(SUBSTR(EMP_NO, 8, 1), '1', '남', '2', '여') >>> 식을 그대로 넣을 수 있음
--GROUP BY 성별
ORDER BY 인원수 DESC;
📌 Ref.
* GROUP BY절이 SELECT절보다 우선 실행되기 때문에 별칭을 GROUP BY에 넣어 사용 불가 (GROUP BY절 실행 시점에 별칭은 생성되기 전)
* ORDER BY절은 가장 마지막 실행순서이므로 SELECT절의 별칭 사용 가능
HAVING 컬럼명 or 함수식 비교연산자 비교값
💁♀️ HAVING절이란,
그룹 함수로 구해올 그룹에 대해 조건을 설정할 때 사용하는 절
- WHERE절의 조건 설정은 그룹함수에서 사용 불가
SELECT
DETP_CODE
, ROUND(AVG(SALARY)) 평균
FROM EMPLOYEE
WHERE SALARY >= 3000000 >>> 일단 WHERE절로 300만원 이하 월급의 직원은 필터링
GROUP BY DEPT_CODE
ORDER BY 1;
SELECT
DETP_CODE
, ROUND(AVG(SALARY)) 평균
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING ROUND(AVG(SALARY)) >= 3000000 >>> 월급 평균이 300만원 이상인 부서 조회 (그룹에 대해 조건걸기)
ORDER BY 1;
💁♀️ 집계함수란,
그룹별로 중간 집계 처리를 하는 함수로써, ROLLUP과 CUBE가 있음
- 그룹 별로 묶인 값에 대한 중간 집계와 총 집계를 구할 때 사용
- GROUP BY절에서만 사용
SELECT
JOB_CODE
, SUM(SALARY)
FROM EMPLOYEE
GROUP BY ROLLUP(JOB_CODE) >>> GROUP BY절 앞에서 사용
ORDER BY 1;
SELECT
JOB_CODE
, SUM(SALARY)
FROM EMPLOYEE
GROUP BY CUBE(JOB_CODE) >>> GROUP BY절 앞에서 사용
ORDER BY 1;
📌 Ref.
* 그룹화한 그룹이 1개일 경우, ROLLUP과 CUBE의 결과는 '동일'
💁♀️ ROLLUP 함수는,
인자로 전달한 그룹 중 가장 먼저인 그룹의 그룹별 합계와 총 합계를 구하는 함수
SELECT
DEPT_CODE
, JOB_CODE
, SUM(SALARY)
FROM EMPLOYEE
GROUP BY ROLLUP(DEPT_CODE, JOB_CODE) >>> 각 부서코드별 중간 합계가 나오고 총 합계 출력
ORDER BY 1;
💁♀️ CUBE 함수는,
그룹으로 지정된 모든 그룹에 대한 중간 집계와 총 합계를 구하는 함수
SELECT
DEPT_CODE
, JOB_CODE
, SUM(SALARY)
FROM EMPLOYEE
GROUP BY CUBE(DEPT_CODE, JOB_CODE) >>> 전달되는 모든 인자의 중간 집계 출력
ORDER BY 1; >>> (두 번째 인자인 JOB_CODE의 중간 집계도 출력)
GROUPING(컬럼명)
: 이 컬럼으로 그룹화 되어있는지 확인 (되어있으면 0, 아니면 1 반환)
💁♀️ GROUPING 함수란,
ROLLUP이나 CUBE에 의한 산출물이 인자로 전달받은 컬럼 집합의 산출물이면 0을 반환하고, 아니면 1을 반환하는 함수
SELECT
DEPT_CODE
, JOB_CODE
, SUM(SALARY)
, COUNT(*)
, GROUPING(DEPT_CODE) "부서별 그룹 묶인 상태"
, GROUPING(JOB_CODE) "직급별 그룹 묶인 상태"
FROM EMPLOYEE
GROUP BY CUBE(DEPT_CODE, JOB_CODE) >>> 이들 중, NULL값을 가진 행은 그룹으로 묶이지 않아 1 반환
ORDER BY 1;
SELECT
NVL(DEPT_CODE, '부서없음') >>> : DEPT_CODE의 값이 NULL일 경우(부서가 없을 경우) '부서없음' 출력
, JOB_CODE
, SUM(SALARY)
, CASE
WHEN GROUPING(NVL(DEPT_CODE, '부서없음')) = 0 AND GROUPING(JOB_CODE) = 1 THEN '부서별합계'
WHEN GROUPING(NVL(DEPT_CODE, '부서없음')) = 1 AND GROUPING(JOB_CODE) = 0 THEN '직급별합계'
WHEN GROUPING(NVL(DEPT_CODE, '부서없음')) = 0 AND GROUPING(JOB_CODE) = 0 THEN '그룹별합계'
ELSE '총합계'
END 구분
FROM EMPLOYEE
GROUP BY CUBE(NVL(DEPT_CODE, '부서없음'), JOB_CODE)
ORDER BY 1;
💁♀️ SET OPERATION이란,
여러 개의 SELECT 결과물을 하나의 쿼리로 만드는 연산자
📍 SET OPERATION의 종류
1) UNION
2) UNIONALL
3) INTERSECT
4) MINUS
💁♀️ UNION은,
여러 개의 쿼리를 하나로 합치는 연산자
- 중복 된 영역을 제외하여 하나로 합침
SELECT
EMP_ID
, EMP_NAME
, DEPT_CODE
, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5' >>> 세미콜론 제거 후 UNION 추가
UNION >>> 위 아래 SELECT절의 중복되는 값 2개를 제거하고 출력
SELECT
EMP_ID
, EMP_NAME
, DEPT_CODE
, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000;
💁♀️ UNION ALL은,
여러 개의 쿼리를 하나로 합치는 연산자
- UNION과는 달리, 중복 영역을 모두 포함시킴
SELECT
EMP_ID
, EMP_NAME
, DEPT_CODE
, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5' >>> 세미콜론 제거 후 UNION ALL추가
UNION ALL >>> 위 아래 SELECT절을 모두 출력
SELECT
EMP_ID
, EMP_NAME
, DEPT_CODE
, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000;
💁♀️ INTERSECT는,
여러 개의 SELECT한 결과에서 공통 부분만 결과로 추출
- 수학에서의 교집합과 유사
SELECT
EMP_ID
, EMP_NAME
, DEPT_CODE
, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5' >>> 세미콜론 제거 후 INTERSECT추가
INTERSECT >>> 위 아래 SELECT절에서 중복되는 값들만을 출력
SELECT
EMP_ID
, EMP_NAME
, DEPT_CODE
, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000;
💁♀️ MINUS는,
선행 SELECT 결과에서 후행 SELECT 결과와 겹치는 부분을 제외한 나머지만 추출
- 수학에서의 차집합과 유사
SELECT
EMP_ID
, EMP_NAME
, DEPT_CODE
, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5' >>> 세미콜론 제거 후 MINUS추가
MINUS >>> 위 SELECT절에서 아래 SELECT절과 겹치는 부분을 제외하고 출력
SELECT
EMP_ID
, EMP_NAME
, DEPT_CODE
, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000;
💁♀️ GROUPING SETS는,
그룹별로 처리된 여러 개의 SELECT문을 하나로 합칠 때 사용하며, SET OPERATION과 결과 동일
SELECT
DEPT_CODE
, JOB_CODE
, MANAGER_ID
, FLOOR(AVG(SALARY))
FROM EMPLOYEE
GROUP BY GROUPING SETS((DEPT_CODE, JOB_CODE, MANAGER_ID)
, (DEPT_CODE, MANAGER_ID)
, (JOB_CODE, MANAGER_ID)
); >>> 1, 2, 3 그룹들 합치기