이 게시글은 패스트캠퍼스의 '데이터베이스와 SQLD 합격패스 Online' 강의를 요약한 내용입니다.
그룹 함수
- 그룹 함수를 이용하여 특정 집합의 소계, 중계, 합계, 총 합계를 구할 수 있다.
종류 | 설명 |
---|---|
ROLLUP | - 소 그룹간의 소계를 계산하는 기능. - ROLLUP함수 내에 인자로 지정된 GROUPING 컬럼은 SUBTOTAL을 생성하는데 사용된다. - GROUPING 컬럼의 수가 N이라고 했을 때, N+1의 SUBTOTAL이 생성된다. - ROLLUP함수 내의 인자의 순서가 바뀌면 결과도 바뀌게 된다. (ROLLUP은 계층 구조) |
CUBE | - 다차원적인 소계를 계산하는 기능. - 결합 가능한 모든 값에 대하여 다차원 집계를 생성. - CUBE 함수 내에 컬럼이 N개라면 2의 N승만큼의 SUBTOTAL이 생성됨. - 시스템에 많은 부담을 주기 때문에 사용상 주의가 필요함. |
GROUPING SETS | - 특정 항목에 대한 소계를 계산하는 기능 |
SELECT A.DEPT_CD "부서코드"
, (SELECT L.DEPT_NM FROM TB_DEPT L WHERE L.DEPT_CD = A.DEPT_CD) AS "부서명"
, COUNT(*) AS "직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO
) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY A.DEPT_CD
ORDER BY A.DEPT_CD
;
SELECT A.DEPT_CD "부서코드"
, (SELECT L.DEPT_NM FROM TB_DEPT L WHERE L.DEPT_CD = A.DEPT_CD) AS "부서명"
, COUNT(*) AS "직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO
) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY ROLLUP(A.DEPT_CD)
ORDER BY A.DEPT_CD ;
SELECT A.DEPT_CD "부서코드"
, (SELECT L.DEPT_NM FROM TB_DEPT L WHERE L.DEPT_CD = A.DEPT_CD) AS "부서명"
, A.SEX_CD AS "성별코드"
, COUNT(*) AS "직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO
) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY ROLLUP(A.DEPT_CD,A.SEX_CD)
ORDER BY A.DEPT_CD, A.SEX_CD
;
SELECT CASE GROUPING(A.DEPT_CD) WHEN 1 THEN '모든부서' ELSE A.DEPT_CD END AS "부서코드"
, (SELECT L.DEPT_NM FROM TB_DEPT L WHERE L.DEPT_CD = A.DEPT_CD) AS "부서명"
, CASE GROUPING(A.SEX_CD) WHEN 1 THEN '모든성별' ELSE A.SEX_CD END AS "성별코드"
, COUNT(*) AS "직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO
) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY ROLLUP(A.DEPT_CD,A.SEX_CD)
ORDER BY A.DEPT_CD, A.SEX_CD
;
SELECT A.DEPT_CD "부서코드"
, (SELECT L.DEPT_NM
FROM TB_DEPT L
WHERE L.DEPT_CD = A.DEPT_CD) AS "부서명"
, A.SEX_CD AS "성별코드"
, COUNT(*) AS "직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO
) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY CUBE(A.DEPT_CD, A.SEX_CD)
ORDER BY A.DEPT_CD ;
SELECT A.DEPT_CD "부서코드", '모든성별' AS "성별코드"
, COUNT(*) AS "직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY A.DEPT_CD
UNION ALL
SELECT '모든부서' AS "부서코드", A.SEX_CD AS "성별코드"
, COUNT(*) AS "부서별직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "부서별연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "부서별평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY A.SEX_CD
ORDER BY "부서코드", "성별코드";
SELECT DECODE(GROUPING(A.DEPT_CD), 1, '모든부서', A.DEPT_CD) AS "부서코드"
, DECODE(GROUPING(A.SEX_CD), 1, '모든성별', A.SEX_CD) AS "성별코드"
, COUNT(*) AS "직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO
) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY GROUPING SETS(A.DEPT_CD, A.SEX_CD)
ORDER BY "부서코드", "성별코드"
;
--GROUPING SET 인자 순서 바꾼 쿼리
SELECT DECODE(GROUPING(A.DEPT_CD), 1, '모든부서', A.DEPT_CD) AS "부서코드"
, DECODE(GROUPING(A.SEX_CD), 1, '모든성별', A.SEX_CD) AS "성별코드"
, COUNT(*) AS "직원수"
, TO_CHAR(TRUNC(SUM(B."연봉")), 'L999,999,999,999') AS "연봉합계"
, TO_CHAR(TRUNC(AVG(B."연봉")), 'L999,999,999,999') AS "평균연봉"
FROM TB_EMP A
, (
SELECT B.EMP_NO
, SUM(B.PAY_AMT) AS "연봉"
FROM TB_SAL_HIS B
WHERE B.PAY_DE BETWEEN '20190101' AND '20191231'
GROUP BY B.EMP_NO
ORDER BY B.EMP_NO
) B
WHERE A.EMP_NO = B.EMP_NO
GROUP BY GROUPING SETS(A.SEX_CD, A.DEPT_CD)
ORDER BY "부서코드", "성별코드"
;