SELECT SUM(SAL)
FROM EMP;
SELECT ENAME, SUM(SAL)
FROM EMP;
결과 값이 한 행으로 나온 데이터 SUM(SAL)과 여러 행이 나올 수 있는 데이터(ENAME)을 함께 명시했기 때문에 오류가 발생한다.
다중행 함수들
함수 | 설명 |
---|---|
SUM | 지정한 데이터의 합 반환 |
COUNT | 지정한 데이터의 개수 반환 |
MAX | 지정한 데이터 중 최댓값 반환 |
MIN | 지정한 데이터 중 최솟값 반환 |
AVG | 지정한 데이터의 평균값 반환 |
SUM함수는 데이터의 합을 구하는 함수이다.
기본 형식
SUM([DISTINCT, ALL 중 하나를 선택하거나
아무 값도 지정하지 않음(선택)]
[합계를 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
SUM([DISTINCT, ALL 중 하나를 선택하거나
아무 값도 지정하지 않음(선택)]
[합계를 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법을 지정)(선택)
SELECT SUM(COMM)
FROM EMP;
SELECT SUM(DISTINCT SAL),
SUM(ALL SAL),
SUM(SAL)
FROM EMP;
COUNT([DISTINCT, ALL 중 하나를 선택하거나
아무 값도 지정하지 않음(선택)]
[개수를 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법 지정)(선택)
SELECT COUNT(*)
FROM EMP;
SELECT COUNT(*)
FROM EMP
WHERE DEPTNO = 30;
SELECT COUNT(DISTINCT SAL),
COUNT(ALL SAL),
COUNT(SAL)
FROM EMP;
SELECT COUNT(COMM)
FROM EMP;
SELECT COUNT(COMM)
FROM EMP
WHERE COMM IS NOT NULL;
SELECT COUNT(COMM)
FROM EMP
WHERE COMM IS NULL;
MAX([DISTINCT, ALL 중 하나를 선택하거나
아무 값도 지정하지 않음(선택)]
[최댓값을 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법 지정)(선택)
MIN([DISTINCT, ALL 중 하나를 선택하거나
아무 값도 지정하지 않음(선택)]
[최솟값을 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법 지정)(선택)
SELECT MAX(SAL)
FROM EMP
WHERE DEPTNO = 10;
SELECT MIN(SAL)
FROM EMP
WHERE DEPTNO = 10;
SELECT MAX(HIREDATE)
FROM EMP
WHERE DEPTNO=20;
SELECT MIN(HIREDATE)
FROM EMP
WHERE DEPTNO=20;
AVG([DISTINCT, ALL 중 하나를 선택하거나
아무 값도 지정하지 않음(선택)]
[평균값을 구할 열이나 연산자, 함수를 사용한 데이터(필수)])
OVER(분석을 위한 여러 문법 지정)(선택)
SELECT AVG(SAL)
FROM EMP
WHERE DEPTNO=30;
SELECT AVG(DISTINCT SAL)
FROM EMP
WHERE DEPTNO=30;
SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 10;
SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 20;
SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 30;
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;
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY [그룹화할 열을 지정(여러개 지정 가능)]
ORDER BY [정렬하려는 열 지정]
SELECT AVG(SAL), DEPTNO
FROM EMP
GROUP BY DEPTNO;
SELECT AVG(SAL), DEPTNO, JOB
FROM EMP
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO, JOB;
SELECT ENAME, DEPTNO, AVG(SAL)
FROM EMP
GROUP BY DEPTNO;
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
HAVING AVG(SAL) >= 2000
ORDER BY DEPTNO, JOB;
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY [그룹화할 열을 지정(여러개 지정 가능)]
HAVING [출력 그룹을 제한하는 조건식]
ORDER BY [정렬하려는 열 지정]
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
WHERE AVG(SAL) >= 2000
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO, JOB;
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
HAVING AVG(SAL) >= 2000
ORDER BY DEPTNO, JOB;
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
WHERE SAL <= 3000
GROUP BY DEPTNO, JOB
HAVING AVG(SAL) >= 2000
ORDER BY DEPTNO, JOB;
GROUP BY로 그룹을 나누는 대상 데이터를 처음부터 제외할 목적이라면 WHERE절을 함께 사용한다.
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);
부서별로 합계 몇인지 출력!
그룹화가 되지 않은 열의 변수는 꼭 ROLLUP안에 넣어주어야 한다.(DPETNO, JOB)
(GROUP BY와 동일하게)
즉, ROLLUP함수에 명시한 열에 한하여 결과가 출력된다.
ROLLUP함수 안에는 그룹함수(COUNT, MAX, MIN, ..)를 지정할 수 없다!
ROLLUP함수는 명시한 열을 소그룹부터 대그룹의 순서로 각 그룹별 결과를 출력하고(여기까지는 일반 GROUP BY와 동일) 마지막에 총 데이터의 결과를 출력한다.
즉, 각 부서의 직책별 사원수, 최고 급여, 급여 합, 평균 급여를 출력하고 마지막에 테이블 전체 데이터를 대상으로 한 사원 수, 최고 급여, 급여 합, 평균 급여를 출력한다.
CUBE 함수를 적용한 그룹화
부서별로 합계 몇인지 출력, 직업별로 합계 몇인지 출력!
SELECT DEPTNO, JOB, COUNT(*), MAX(SAL), SUM(SAL), AVG(SAL)
FROM EMP
GROUP BY CUBE(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;
ROLLUP(A, B, C)
- A그룹별 B그룹별 C그룹에 해당하는 결과 출력
- A그룹별 B그룹에 해당하는 결과 출력
- A그룹에 해당하는 결과 출력
- 전체 데이터 결과 출력
CUBE(A, B, C)
- A그룹별 B그룹별 C그룹에 해당하는 결과 출력
- A그룹별 B그룹에 해당하는 결과 출력
- B그룹별 C그룹에 해당하는 결과 출력
- A그룹별 C그룹에 해당하는 결과 출력
- A그룹에 해당하는 결과 출력
- B그룹에 해당하는 결과 출력
- C그룹에 해당하는 결과 출력
- 전체 데이터 결과 출력
SELECT DEPTNO, JOB, COUNT(*)
FROM EMP
GROUP BY DEPTNO, rollup(JOB);
SELECT DEPTNO, JOB, COUNT(*)
FROM EMP
GROUP BY JOB, rollup(DEPTNO);
특정 직업을 가진 사람들의 부서별 인원수와 각 직업별 사원 수의 합 출력
ROLLUP, CUBE가 익숙치 않다면, 다음의 단계를 따르며 차근차근 접근하자
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), MIN(SAL), AVG(SAL),
GROUPING(DEPTNO),
GROUPING(JOB)
FROM EMP
GROUP BY CUBE(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;
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 [GROUP BY절에 ROLLUP 또는 CUBE에 명시한 그룹화 할 열 이름]
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 DEPTNO, ENAME
FROM EMP
GROUP BY DEPTNO, ENAME;
SELECT [조회할 열 1 이름], [열2 이름], ..., [열N 이름]
LISTAGG([나열할 열(필수)], [각 데이터를 구분하는 구분자(선택)])
WITHIN GROUP(ORDER BY 나열할 열의 정렬 기준 열(선택)])
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하는 조건식]
GROUP BY ([그룹화할 열]);;
SELECT DEPTNO,
LISTAGG(ENAME, ',')
WITHIN GROUP(ORDER BY SAL DESC) AS ENAMES
FROM EMP
GROUP BY DEPTNO;
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 DEPTNO, JOB, 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;
서브쿼리(subquery): FROM절 안에 다시 SELECT문이 들어가 있는 형태
DECODE문을 활용하여 PIVOT 함수와 같은 출력 구현하기
(오라클 버전이 11g 이전 버전일 경우에는 이 방식을 사용해야 할 수도 있다.)
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;
SELECT DEPTNO, TRUNC(AVG(SAL)), MAX(SAL), MIN(SAL), COUNT(*) AS CNT
FROM EMP
GROUP BY DEPTNO;
SELECT JOB, COUNT(*)
FROM EMP
GROUP BY JOB
HAVING COUNT(*) >= 3;
SELECT
TO_CHAR(HIREDATE, 'YYYY') AS HIRE_YEAR,
DEPTNO,
COUNT(*) AS CNT
FROM EMP
GROUP BY
TO_CHAR(HIREDATE, 'YYYY'),
DEPTNO;
SELECT
CASE
WHEN COMM IS NULL THEN 'X'
WHEN COMM IS NOT NULL THEN 'O'
END AS EXIST_COMM,
COUNT(*) AS CNT
FROM EMP
GROUP BY
CASE
WHEN COMM IS NULL THEN 'X'
WHEN COMM IS NOT NULL THEN 'O'
END;
SELECT NVL2(COMM, 'O', 'X') AS EXIXT_COMM,
COUNT(*) AS CNT
FROM EMP
GROUP BY NVL2(COMM, 'O', 'X');
SELECT DEPTNO,
TO_CHAR(HIREDATE, 'YYYY') AS HIRE_DATE,
COUNT(*) AS CNT,
MAX(SAL) AS MAX_SAL,
SUM(SAL) AS SUM_SAL,
AVG(SAL) AS AVG_SAL
FROM EMP
GROUP BY
ROLLUP(DEPTNO, TO_CHAR(HIREDATE, 'YYYY'));