다중 행 함수(Multi-Row Function)
여러 행의 그룹에 대해 적용되는 함수
그룹 함수(Group Function)
COUNT, SUM, AVG, MAX, MIN 등ROLLUP, CUBE, GROUPING SETS윈도우 함수(Window Function)
SELECT, HAVING, ORDER BY 절에 사용 가능GROUP BY 절을 통해 그룹핑 기준을 명시하여 사용이미지 내용을 바탕으로 블로그에 올릴 수 있도록 정리해드리겠습니다.
NULL을 제외하고 계산
(DISTINCT | ALL) 옵션
ALL
GROUP BY
소그룹별 집계
GROUP BY 절을 사용해 POSITION별로 COUNT와 AVG를 구할 수 있습니다.
SELECT POSITION, COUNT(*) 전체행수, COUNT(HEIGHT) 키값수, ROUND(AVG(HEIGHT), 2) 평균키
FROM PLAYER
GROUP BY POSITION;
전체 테이블을 하나의 그룹으로
테이블 전체가 하나의 그룹이면 GROUP BY 절을 생략할 수 있습니다.
SELECT COUNT(*) 전체행수, COUNT(HEIGHT) 키값수, ROUND(AVG(HEIGHT), 2) 평균키
FROM PLAYER;
집계 함수에 조건 부여
예) 포지션별 키의 평균이 180 이상인 경우만 출력
SELECT POSITION, ROUND(AVG(HEIGHT), 2) 평균키
FROM PLAYER
GROUP BY POSITION
HAVING AVG(HEIGHT) >= 180;
WHERE 절 사용 시 에러 발생
WHERE 절은 GROUP BY 절보다 먼저 수행되므로 집계 결과에 조건을 붙일 때는 HAVING을 사용해야 합니다.
SELECT POSITION, ROUND(AVG(HEIGHT), 2) 평균키
FROM PLAYER
WHERE AVG(HEIGHT) >= 180; -- 오류 발생
GROUP BY POSITION;
그룹핑 기준이 여러 개인 경우, GROUP BY에 여러 컬럼을 지정하여 복합적인 그룹핑을 할 수 있습니다.
SELECT DNAME, JOB, COUNT(*) 직원수, SUM(SAL) AS 급여합
FROM EMP, DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY DNAME, JOB
ORDER BY DNAME, JOB;
SELECT 문장 구조 및 실행 순서
SELECT 문장 구조
SELECT POSITION, ROUND(AVG(HEIGHT), 2) AS 평균키
FROM PLAYER
WHERE HEIGHT IS NOT NULL
GROUP BY POSITION
HAVING AVG(HEIGHT) > 190
ORDER BY AVG(HEIGHT) DESC;실제 실행 순서
ROWNUM은 SELECT 결과에서 각 행에 번호를 부여하지만, WHERE 절보다 먼저 적용되어 주의가 필요하다.
예를 들어, 키가 가장 작은 3명의 선수를 조회하고자 할 때는 다음과 같이 잘못된 쿼리와 수정된 쿼리를 구분하여 작성해야 한다.
-- 잘못된 쿼리
SELECT PLAYER_NAME, HEIGHT, ROWNUM
FROM PLAYER
WHERE ROWNUM < 4
ORDER BY HEIGHT;
-- 수정된 쿼리
SELECT PLAYER_NAME, HEIGHT, ORGNO, ROWNUM
FROM (SELECT PLAYER_NAME, HEIGHT, ROWNUM AS ORGNO
FROM PLAYER
ORDER BY HEIGHT)
WHERE ROWNUM < 4;
WHERE, ORDER BY 절에서의 유효 범위
SELECT PLAYER_NAME, HEIGHT
FROM PLAYER
WHERE POSITION = 'MF'
ORDER BY TEAM_ID;GROUP BY 사용 시 유효 범위
SELECT TEAM_ID, COUNT(*) AS 인원
FROM PLAYER
GROUP BY TEAM_ID
HAVING AVG(HEIGHT) > 178
ORDER BY AVG(HEIGHT);인라인 뷰 사용 시 유효 범위
-- 올바른 쿼리
SELECT PLAYER_NAME, HEIGHT
FROM (SELECT PLAYER_NAME, HEIGHT, POSITION FROM PLAYER WHERE POSITION = 'MF')
ORDER BY POSITION;고급 집계 함수 ROLLUP, CUBE, GROUPING SETS
ROLLUP은 계층적으로 집계하여, 한 방향으로 누적되는 집계를 제공한다. 주로 보고서의 총합과 부분합을 계산할 때 유용하다.
GROUP BY ROLLUP (DNAME, JOB);DNAME, JOB 순서로 집계DNAME별로 JOB에 대한 세부 집계를 하고, DNAME별 합계를 구한다.ACCOUNTING 부서의 CLERK, MANAGER 등의 역할별 집계와, ACCOUNTING 부서 전체의 합계, 마지막에 전체 합계를 보여준다.CUBE는 모든 가능한 조합에 대한 집계를 제공한다. ROLLUP과 다르게 다양한 방향으로 집계가 이루어진다.
GROUP BY CUBE (DNAME, JOB);DNAME과 JOB의 모든 조합에 대해 부분합을 계산한다.DNAME별 합계, JOB별 합계, 그리고 전체 합계를 모두 포함한다.DNAME별 합계, JOB별 합계, 둘 다 합계에 포함된다.ACCOUNTING 부서의 모든 역할별 집계, 각 역할별 총합, 그리고 전체 합계를 포함한다.GROUPING SETS는 특정 그룹 조합을 지정하여 원하는 부분 집계만 수행할 수 있는 유연성을 제공한다.
GROUP BY GROUPING SETS ((DNAME, JOB), (DNAME), (JOB));DNAME과 JOB의 조합에 대해서만 집계를 수행하며, 필요한 집합만을 대상으로 집계를 수행한다.DNAME과 JOB의 조합 및 DNAME별 집계, JOB별 집계를 지정할 수 있다.| 기능 | ROLLUP | CUBE | GROUPING SETS |
|---|---|---|---|
| 집계 방식 | 단방향, 누적 집계 | 모든 조합의 집계 | 특정 조합을 선택적으로 집계 |
| 활용도 | 계층적 보고서, 총합/부분합 계산 | 다양한 조합 집계 | 유연한 집계가 필요한 경우 |
| 예시 결과 | 부서-역할별 합계와 전체 합계 | 모든 부서/역할 조합의 합계 | 원하는 부서/역할 조합의 합계만 계산 |
이와 같이, ROLLUP은 계층적, CUBE는 모든 조합, GROUPING SETS는 선택적 조합에 유용하다.

윈도우 함수(Window Function)
RANK, DENSE_RANK, ROW_NUMBERSUM, MAX, MIN, AVG, COUNTFIRST_VALUE, LAST_VALUE, LAG, LEADRATIO_TO_REPORT, PERCENT_RANK, NTILECORR, STDEV, VARIANCE 등SELECT WINDOW_FUNCTION(ARGUMENTS) OVER(
[PARTITION BY 칼럼]
[ORDER BY 절]
[WINDOWING 절]
)
FROM 테이블 명;
| 표현식 | 해석 |
|---|---|
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING | 현재 행의 앞 한 행, 현재 행, 뒤 한 행을 범위로 지정 |
RANGE BETWEEN 50 PRECEDING AND 150 FOLLOWING | 현재 행의 값 - 50에서 (현재 행의 값 + 150)을 범위로 지정 |
RANGE UNBOUNDED PRECEDING | 현재 파티션의 첫 행부터 현재 행까지 지정 |
순위 윈도우 함수
RANK 함수
DENSE_RANK 함수
ROW_NUMBER 함수
SELECT
JOB,
ENAME,
SAL,
RANK() OVER (ORDER BY SAL DESC) AS RANK,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS DENSE_RANK,
ROW_NUMBER() OVER (ORDER BY SAL DESC) AS ROW_NUMBER
FROM EMP;
RANK: 동일한 급여 값이 있는 경우 같은 순위가 부여되고, 그 다음 순위는 건너뛰게 됩니다.DENSE_RANK: 동일한 급여 값에 같은 순위가 부여되지만, 다음 순위는 연속적으로 이어집니다.ROW_NUMBER: 동일한 급여 값이어도 각 행에 대해 고유한 순위를 부여합니다.집계 윈도우 함수
윈도우 함수는 데이터베이스에서 여러 행에 걸쳐 계산을 수행할 때 사용되며, 특정 집계 값을 계산하면서도 원본 데이터의 각 행을 그대로 출력할 수 있는 강력한 기능입니다.
MAX(SAL) OVER (PARTITION BY JOB) AS JOB_MAX 구문을 사용하여 직업(JOB)별로 최대 급여를 계산하고, 이를 각 행에 표시.SUM(SAL) OVER (PARTITION BY JOB ORDER BY SAL DESC RANGE UNBOUNDED PRECEDING) 구문을 통해 급여 내림차순으로 정렬된 상태에서, 본인 급여를 포함하여 높은 급여를 받는 직원들의 합계를 계산.ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING를 사용해 본인의 위아래 한 행을 포함한 범위에서 합계를 계산.COUNT(*) OVER (ORDER BY SAL RANGE BETWEEN 100 PRECEDING AND 200 FOLLOWING) 구문을 통해 본인 급여를 기준으로, 범위 내의 직원 수를 계산.행 순서 윈도우 함수
예제 설명
SELECT DEPTNO, ENAME, SAL,
FIRST_VALUE(ENAME) OVER (PARTITION BY DEPTNO ORDER BY SAL DESC, ENAME ASC) AS RICH_EMP
FROM EMP;
RICH_EMP 컬럼에 출력합니다.PARTITION BY DEPTNO는 부서별로 파티션을 나누는 역할을 하며, ORDER BY SAL DESC로 급여 순서에 따라 정렬됩니다.예제 설명 1
SELECT ENAME, SAL,
LAG(SAL, 1) OVER (ORDER BY SAL DESC) AS HIGHER_SAL,
LEAD(SAL, 1) OVER (ORDER BY SAL DESC) AS LOWER_SAL
FROM EMP
WHERE JOB = 'SALESMAN';
LAG(SAL, 1)은 바로 이전 사람의 급여를 가져오고, LEAD(SAL, 1)은 바로 다음 사람의 급여를 가져옵니다.JOB이 'SALESMAN'인 직원들에 대해 급여 순서에 따라 본인의 윗 사람과 아랫 사람의 급여를 함께 출력합니다.예제 설명 2
SELECT ENAME, SAL,
LAG(SAL, 2, 0) OVER (ORDER BY SAL DESC) AS HIGHER_SAL
FROM EMP;
LAG(SAL, 2, 0)은 두 번째 이전 사람의 급여를 가져오며, 값이 없을 경우 0으로 채웁니다.비율 윈도우 함수
FIRST_VALUE (or LAST_VALUE) 함수
예제 설명:
SELECT DEPTNO, ENAME, SAL,
FIRST_VALUE(ENAME) OVER (PARTITION BY DEPTNO ORDER BY SAL DESC, ENAME ASC) AS RICH_EMP
FROM EMP;
이 쿼리는 각 부서(DEPTNO)별로 가장 높은 급여를 받는 직원의 이름을 RICH_EMP 컬럼에 출력합니다.
PARTITION BY DEPTNO는 부서별로 파티션을 나누며, ORDER BY SAL DESC는 급여 순서대로 정렬합니다.
LAG (or LEAD) 함수
예제 설명 1:
SELECT ENAME, SAL,
LAG(SAL, 1) OVER (ORDER BY SAL DESC) AS HIGHER_SAL,
LEAD(SAL, 1) OVER (ORDER BY SAL DESC) AS LOWER_SAL
FROM EMP
WHERE JOB = 'SALESMAN';
LAG(SAL, 1)은 바로 이전 사람의 급여를 가져오고, LEAD(SAL, 1)은 바로 다음 사람의 급여를 가져옵니다.
JOB이 'SALESMAN'인 직원들에 대해 급여 순서에 따라 본인의 윗 사람과 아랫 사람의 급여를 함께 출력합니다.
예제 설명 2:
SELECT ENAME, SAL,
LAG(SAL, 2, 0) OVER (ORDER BY SAL DESC) AS HIGHER_SAL
FROM EMP;
LAG(SAL, 2, 0)은 두 번째 이전 사람의 급여를 가져오며, 값이 없을 경우 0으로 채웁니다.