
여러 행을 바탕으로 하나의 결과 값을 도출해내기 위해 사용하는 함수
SELECT SUM(SAL)
FROM EMP;
| SUM(SAL) |
|---|
| 29025 |
SELECT ENAME, SUM(SAL)
FROM EMP;
1행에 오류: ORA-00937: 단일 그룹의 그룹 함수가 아닙니다
SUM : 지정한 데이터의 합 변환COUNT : 지정한 데이터의 개수 반환MAX : 지정한 데이터 중 최댓값 반환MIN : 지정한 데이터 중 최솟값 반환AVG : 지정한 데이터의 평균값 반환SUM([DISTINCT, ALL 중 하나를 선택하거나 아무 값도 지정하지 않음(선택)]
[합계를 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법 지정)(선택)
SELECT SUM(DISTINCT SAL),
SUM(ALL SAL),
SUM(SAL)
FROM EMP;
| SUM(DISTINCTSAL) | SUM(ALLSAL) | SUM(SAL) |
|---|---|---|
| 24775 | 29025 | 29025 |
결과 행의 개수를 출력
COUNT([DISTINCT, ALL 중 하나를 선택하거나 아무 값도 지정하지 않음(선택)]
[개수를 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법 지정)(선택)
SELECT COUNT(DISTINCT SAL),
COUNT(ALL SAL),
COUNT(SAL),
COUNT(*) AS STAR
FROM EMP;
| COUNT(DISTINCTSAL) | COUNT(ALLSAL) | COUNT(SAL) | STAR |
|---|---|---|---|
| 12 | 14 | 14 | 14 |
MAX([DISTINCT, ALL 중 하나를 선택하거나 아무 값도 지정하지 않음(선택)]
[최댓값을 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법 지정)(선택)
MIN([DISTINCT, ALL 중 하나를 선택하거나 아무 값도 지정하지 않음(선택)]
[최솟값을 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법 지정)(선택)
AVG([DISTINCT, ALL 중 하나를 선택하거나 아무 값도 지정하지 않음(선택)]
[평균 값을 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법을 지정)(선택)
결과 값을 원하는 열로 묶어 출력
SELECT AVG(SAL), '10' AS DEPTNO FROM EMP WHERE DEPTNO = 10
UNION ALL
SELECT AVG(SAL), '20' AS DEPTNO FROM EMP WHERE DEPTNO = 20
UNION ALL
SELECT AVG(SAL), '30' AS DEPTNO FROM EMP WHERE DEPTNO = 30;
| AVG(SAL) | DEPTNO |
|---|---|
| 2916.66667 | 10 |
| 2175 | 20 |
| 1566.66667 | 30 |
별칭 사용 가능
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY [그룹화할 열을 지정(여러 개 지정 가능)]
ORDER BY [정렬하려는 열 지정]
SELECT AVG(SAL), DEPTNO
2 FROM EMP
3 GROUP BY DEPTNO;
| AVG(SAL) | DEPTNO |
|---|---|
| 1566.66667 | 30 |
| 2175 | 20 |
| 2916.66667 | 10 |
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO, JOB;
| DEPTNO | JOB | AVG(SAL) |
|---|---|---|
| 10 | CLERK | 1300 |
| 10 | MANAGER | 2450 |
| 10 | PRESIDENT | 5000 |
| 20 | ANALYST | 3000 |
| 20 | CLERK | 950 |
| 20 | MANAGER | 2975 |
| 30 | CLERK | 950 |
| 30 | MANAGER | 2850 |
| 30 | SALESMAN | 1400 |
다중행 함수를 사용하지 않은 일반 열은 GROUP BY절에 명시하지 않으면 SELECT절에서 사용할 수 없음
SELECT ENAME, DEPTNO, AVG(SAL)
FROM EMP
GROUP BY DEPTNO;
1행에 오류: ORA-00979: GROUP BY 표현식이 아닙니다.
GROUP BY절을 통해 그룹화된 결과 값의 범위를 제한하는 데 사용
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
HAVING AVG(SAL) >= 2000
ORDER BY DEPTNO, JOB;
| DEPTNO | JOB | AVG(SAL) |
|---|---|---|
| 10 | MANAGER | 2450 |
| 10 | PRESIDENT | 5000 |
| 20 | ANALYST | 3000 |
| 20 | MANAGER | 2975 |
| 30 | MANAGER | 2850 |
별칭 사용 가능
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY [그룹화할 열을 지정(여러 개 지정 가능)]
HAVING [출력 그룹을 제한하는 조건 식]
ORDER BY [정렬하려는 열 지정]
출력 결과를 제한하기 위해 HAVING을 사용하지 않고 조건식을 WHERE에 명시하면 에러 발생
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
WHERE AVG(SAL) >= 2000
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO, JOB;
3행에 오류: ORA-00934: 그룹 함수는 허가되지 않습니다
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
WHERE SAL <= 3000 -- 먼저 실행
GROUP BY DEPTNO, JOB
HAVING AVG(SAL) >= 2000 -- 나중에 실행
ORDER BY DEPTNO, JOB;
| DEPTNO | JOB | AVG(SAL) |
|---|---|---|
| 10 | MANAGER | 2450 |
| 20 | ANALYST | 3000 |
| 20 | MANAGER | 2975 |
| 30 | MANAGER | 2850 |
그룹화 데이터의 합계를 출력할 때 유용하게 사용
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY ROLLUP [그룹화 열 지정(여러 개 지정 가능)];
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY CUBE [그룹화 열 지정(여러 개 지정 가능)];
SELECT DEPTNO, JOB, COUNT(*), MAX(SAL), SUM(SAL), AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO, JOB;

SELECT DEPTNO, JOB, COUNT(*), MAX(SAL), SUM(SAL), AVG(SAL)
FROM EMP
GROUP BY ROLLUP(DEPTNO, JOB);
SELECT DEPTNO, JOB, COUNT(*), MAX(SAL), SUM(SAL), AVG(SAL)
FROM EMP
GROUP BY CUBE(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;
| ROLLUP | CUBE |
|---|---|
![]() |
![]() |
SELECT DEPTNO, JOB, COUNT(*)
FROM EMP
GROUP BY DEPTNO, ROLLUP(JOB);
SELECT DEPTNO, JOB, COUNT(*)
FROM EMP
GROUP BY JOB, ROLLUP(DEPTNO);
| DEPTNO를 먼저 그룹화 | JOB을 먼저 그룹화 |
|---|---|
![]() |
![]() |
같은 수준의 그룹화 열이 여러 개일 때 각 열별 그룹화를 통해 결과 값을 출력
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY GROUPING SETS [그룹화 열 지정(여러 개 지정 가능)];
SELECT DEPTNO, JOB, COUNT(*)
FROM EMP
GROUP BY GROUPING SETS(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;

데이터 자체의 가공이나 특별한 연산 기능을 수행하지는 않지만 그룹화 데이터의 식별이 쉽고 가독성을 높이기 위한 목적으로 사용
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
GROUPING [GROUP BY절에 ROLLUP 또는 CUBE에 명시한 그룹화 할 열 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY ROLLUP 또는 CUBE [그룹화할 열];
SELECT DEPTNO, JOB, COUNT(*), MAX(SAL), SUM(SAL), AVG(SAL),
GROUPING(DEPTNO),
GROUPING(JOB)
FROM EMP
GROUP BY CUBE(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;

0 : GROUPING 함수에 지정한 열이 그룹화되었음1 : GROUPING 함수에 지정한 열이 그룹화되지 않았음SELECT DECODE(GROUPING(DEPTNO), 1, 'ALL_DEPT', DEPTNO) AS DEPTNO,
DECODE(GROUPING(JOB), 1, 'ALL_JOB', JOB) AS JOB,
COUNT(*), MAX(SAL), SUM(SAL), AVG(SAL)
FROM EMP
GROUP BY CUBE(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;

SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
GROUPING_ID [그룹화 여부를 확인할 열(여러 개 지정 가능)]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY ROLLUP 또는 CUBE [그룹화할 열];
| 그룹화 된 열 | 그룹화 비트 벡터 | 최종 결과 |
|---|---|---|
| A, B | 0 0 | 0 |
| A | 0 1 | 1 |
| B | 1 0 | 2 |
| 없음 | 1 1 | 3 |
SELECT DEPTNO, JOB, COUNT(*), SUM(SAL),
GROUPING(DEPTNO),
GROUPING(JOB),
GROUPING_ID(DEPTNO, JOB)
FROM EMP
GROUP BY CUBE(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;

SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
LISTAGG([나열할 열(필수)], [각 데이터를 구분하는 구분자(선택)])
WITHIN GROUP(ORDER BY 나열할 열의 정렬 기준 열(선택)
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
SELECT DEPTNO, ENAME
FROM EMP
GROUP BY DEPTNO, ENAME;
SELECT DEPTNO,
LISTAGG(ENAME, ', ')
WITHIN GROUP(ORDER BY SAL DESC) AS ENAMES
FROM EMP
GROUP BY DEPTNO;
| BEFORE LISTAGG | AFTER LISTAGG |
|---|---|
![]() |
![]() |
PIVOT : 기존 테이블 행을 열로 바꿈UNPIVOT : 기존 테이블 열을 행으로 바꿈SELECT DEPTNO, JOB, MAX(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO, JOB;

SELECT *
FROM(SELECT DEPTNO, JOB, SAL
FROM EMP)
PIVOT(MAX(SAL)
FOR DEPTNO IN (10, 20, 30)
)
ORDER BY JOB;

SELECT *
FROM(SELECT JOB, DEPTNO, SAL
FROM EMP)
PIVOT(MAX(SAL)
FOR JOB IN ('CLERK' AS CLERK,
'SALESMAN' AS SALESMAN,
'PRESIDENT' AS PRESIDENT,
'MANAGER' AS MANAGER,
'ANALYST' AS ANALYST)
)
ORDER BY DEPTNO;

SELECT DEPTNO,
MAX(DECODE(JOB, 'CLERK', SAL)) AS "CLERK",
MAX(DECODE(JOB, 'SALESMAN', SAL)) AS "SALESMAN",
MAX(DECODE(JOB, 'PRESIDENT', SAL)) AS "PRESIDENT",
MAX(DECODE(JOB, 'MANAGER', SAL)) AS "MANAGER",
MAX(DECODE(JOB, 'ANALYST', SAL)) AS "ANALYST"
FROM EMP
GROUP BY DEPTNO
ORDER BY DEPTNO;

SELECT *
FROM(SELECT DEPTNO,
MAX(DECODE(JOB, 'CLERK', SAL)) AS "CLERK",
MAX(DECODE(JOB, 'SALESMAN', SAL)) AS "SALESMAN",
MAX(DECODE(JOB, 'PRESIDENT', SAL)) AS "PRESIDENT",
MAX(DECODE(JOB, 'MANAGER', SAL)) AS "MANAGER",
MAX(DECODE(JOB, 'ANALYST', SAL)) AS "ANALYST"
FROM EMP
GROUP BY DEPTNO
ORDER BY DEPTNO)
UNPIVOT(SAL FOR JOB IN (CLERK, SALESMAN, PRESIDENT, MANAGER, ANALYST))
ORDER BY DEPTNO, JOB;
