1. Window Function 개요
윈도우 함수랑 행과 행간의 관계를 쉽게 정의하기 위해 만든 함수를 말한다. 분석 함수(ANALYSTIC FUNCTION)이나 순위 함수(RANK FUNCTION)등이 해당된다. 서브쿼리는 사용이 가능하고, 중첩(NEST)해서는 사용이 불가하다.
WINDOW FUNCTION 종류
| 구분 | 함수 | 지원 정보 |
| 그룹 내 순위(RANK) 관련 함수 | RANK, DENSE_RANK, ROW_NUMBER | ANSI/ISO SQL 표준과 Oracle, SQL Sever등 대부분의 DBMS에서 지원 |
| 그룹 내 집계(AGGREGATE) 관련 함수 | SUM ,MAX, MIN, AVG, COUNT | ANSI/ISO SQL 표준과 Oracle, SQL Server 등 대부분의 DBMS 에서 지원 SQL Server 의 경우 집계 함수는 뒤에서 설명할 OVER 절의 내의 ORDER BY 지원 하지 않음 |
| 그룹 내 행 순서 관련 함수 | FIRST_VALUE, LAST_VALUE, LAG, LEAD | ORACLE에서만 지원 |
| 그룹 내 비율 관련 함수 |
CUME_DIST, PERCENT_RANK | ANSI/ISO SQL 표준과 Oracle, MS SQL에서 지원 |
| NTILE | ORACLE, MS SQL에서 지원 | |
| RATIO_TO_REPORT | ORACLE 에서만 지원 |
SYNTAX
SELECT WINDOW_FUNCTION (ARGUMENTS) OVER
( [PARTITION BY 컬럼][ORDER BY 절][WINDOWING 절])
FROM 테이블 명;
-- WINDOW_FUNCTION : 윈도우함수
-- ARGUMENTS : 함수에 따라 0~N개의 인수가 저장
-- OVER : Window 함수 사용에 있어 OVER 문구는 필수 키워드이다.
-- PARTITION BY 절 : 전체 집합을 기준에 대해 순위를 지정할 지 ORDER BY 절을 기술
-- WINDOWING절 : WINDOWS 절은 함수의 대상이 되는 행 기준의 범위를 강력하게 지정할 수 있다.
--ROWS는 물리적인 결과 행의 수, RANGE는 논리적인 값에 의한 범위를, 둘 중 하나 선택 사용
--WINDOWING절은 SQL Server에서는 지원하지 않는다.
WINDOWING 절 SYNTAX 상세
ROWS | RANGE BETWEEN UNBOUNDED PRECEDING[CURRENT ROW] AND UNBOUNDED FOLLOWING[CURRENT ROW]
ROWS : 물리적인 행을 의미
RANGE : 논리적인 값으로 범위를 지정 / 같은값을 하나로 본다
WINDOWINDG 기본 설정값이 존재 : UNBOUNDED PRECEDING
UNBOUNDED PRECEDING : 현재행을 기준으로 선행(이전)하는 모든 행들
SELECT empno, ename, sal ,
SUM(sal) OVER (ORDER BY sal ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) c_sum
FROM emp
ORDER BY sal;
UNBOUNDED FOLLOWING : 현재행을 기준으로 이후 모든 행들
n PRECEDING : 현재행을 기준으로 n칸 앞
n FOLLWING : 현재행을 기준으로 n칸 뒤
그룹 내 비율 함수
* 칼럼 값에 대한 백분율 -> RATIO_TO_REPORT
* 행의 순서에 대한 (0부터 1사이 값) 백분율 -> PERCENT_RANK
* 1 / (파티션) 전체 건수로 표현하는 백분율 -> CUME_DIST
RATIO_TO_REPORT 함수
파티션 내 전체 SUM(칼럼) 값에 대한 행별 칼럼 값의 백분율을 소수점으로 구함
* 0 < 백분율 < 1, 개별 RATIO의 합 = 1
SQL Sever 에서는 지원하지 않는 함수
SELECT FIRST_NAME, SALARY,
ROUND(RATIO_TO_REPORT(SALARY) OVER (),2) AS R_R,
SUM(SALARY) Over ( Order by JOB_ID ) AS "Total"
FROM EMPLOYEES e
WHERE JOB_ID='SA_REP' ;
FIRST_NAME |SALARY|R_R |Total |
-----------+------+----+------+
Peter | 10000|0.04|250500|
David | 9500|0.04|250500|
Peter | 9000|0.04|250500|
Christopher| 8000|0.03|250500|
Nanette | 7500|0.03|250500|
Oliver | 7000|0.03|250500|
Janette | 10000|0.04|250500|
Patrick | 9500|0.04|250500|
Allan | 9000|0.04|250500|
Lindsey | 8000|0.03|250500|
Louise | 7500|0.03|250500|
Sarath | 7000|0.03|250500|
Clara | 10500|0.04|250500|
Danielle | 9500|0.04|250500|
Mattea | 7200|0.03|250500|
David | 6800|0.03|250500|
...
PERCENT_RANK
파티션 별 윈도우에서 제일 먼저 나오는 것을 0으로, 제일 늦게 나오는 것을 1로 하여 값이 아닌 행의 순서별 백분율을 구함
* 0 < 백분율 < 1
같은 부서 소속 사원들의 집합에서 본인의 급여가 순서상 몇 번째 위치쯤에 있는지 0과 1사이의 값으로 출력
SELECT DEPARTMENT_ID, FIRST_NAME, SALARY,
PERCENT_RANK() OVER ( PARTITION BY DEPARTMENT_ID ORDER BY SALARY DESC ) AS P_R
FROM EMPLOYEES e ;
DEPARTMENT_ID|FIRST_NAME |SALARY|P_R |
-------------+-----------+------+------------------------------------------+
10|Jennifer | 4400| 0|
20|Michael | 13000| 0|
20|Pat | 6000| 1|
30|Den | 11000| 0|
30|Alexander | 3100| 0.2|
30|Shelli | 2900| 0.4|
30|Sigal | 2800| 0.6|
30|Guy | 2600| 0.8|
30|Karen | 2500| 1|
40|Susan | 6500| 0|
50|Adam | 8200| 0|
...
CUME_DIST
파티션 별 윈도우에서 전체 건수에 현재 행보다 작거나 같은 건수에 대한 누적 백분율을 구함
* 0 < 백분율 < 1
같은 부서 소속 사원들의 집합에서 본인의 급여가 누적 순서상 몇 번째 위치쯤에 있는지 0과 1사이의 값으로 출력
SELECT DEPARTMENT_ID, FIRST_NAME, SALARY,
CUME_DIST() OVER ( PARTITION BY DEPARTMENT_ID ORDER BY SALARY ) AS C_D
FROM EMPLOYEES e ;
DEPARTMENT_ID|FIRST_NAME |SALARY|C_D |
-------------+-----------+------+------------------------------------------+
10|Jennifer | 4400| 1|
20|Pat | 6000| 0.5|
20|Michael | 13000| 1|
30|Karen | 2500|0.1666666666666666666666666666666666666667|
30|Guy | 2600|0.3333333333333333333333333333333333333333|
30|Sigal | 2800| 0.5|
30|Shelli | 2900|0.6666666666666666666666666666666666666667|
30|Alexander | 3100|0.8333333333333333333333333333333333333333|
30|Den | 11000| 1|
40|Susan | 6500| 1|
...
NFILE
파티션 별 전체 건수를 ARGUMENT 값으로 N등분 한 결과 구함
사원들을 연봉이 높은 순으로 정렬 해서 4단계로 나눠 보여주는 예제
SELECT FIRST_NAME, SALARY, NTILE(4) OVER (ORDER BY SALARY DESC ) AS QUAR_TILE
FROM EMPLOYEES e ;
FIRST_NAME |SALARY|QUAR_TILE|
-----------+------+---------+
Steven | 24000| 1|
Neena | 17000| 1|
Lex | 17000| 1|
John | 14000| 1|
Karen | 13500| 1|
Michael | 13000| 1|
Nancy | 12008| 1|
Shelley | 12008| 1|
Alberto | 12000| 1|
Lisa | 11500| 1|
Den | 11000| 1|
Gerald | 11000| 1|
Ellen | 11000| 1|
Eleni | 10500| 1|
Clara | 10500| 1|
Janette | 10000| 1|
Peter | 10000| 1|
Hermann | 10000| 1|
Harrison | 10000| 1|
Tayler | 9600| 1|
Danielle | 9500| 1|
David | 9500| 1|
Patrick | 9500| 1|
Peter | 9000| 1|
Alexander | 9000| 1|
Allan | 9000| 1|
Daniel | 9000| 1|
Alyssa | 8800| 2|
Jonathon | 8600| 2|
Jack | 8400| 2|
William | 8300| 2|
Adam | 8200| 2|
John | 8200| 2|
Matthew | 8000| 2|
Lindsey | 8000| 2|
Christopher| 8000| 2|
Payam | 7900| 2|
Jose Manuel| 7800| 2|
Ismael | 7700| 2|
Louise | 7500| 2|
Nanette | 7500| 2|
William | 7400| 2|
Elizabeth | 7300| 2|
Mattea | 7200| 2|
Oliver | 7000| 2|
Kimberely | 7000| 2|
Sarath | 7000| 2|
Luis | 6900| 2|
David | 6800| 2|
Susan | 6500| 2|
Shanta | 6500| 2|
Sundar | 6400| 2|
Charles | 6200| 2|
Amit | 6200| 2|
Sundita | 6100| 3|
Pat | 6000| 3|
Bruce | 6000| 3|
Kevin | 5800| 3|
Valli | 4800| 3|
David | 4800| 3|
Jennifer | 4400| 3|
Nandita | 4200| 3|
Diana | 4200| 3|
Alexis | 4100| 3|
Sarah | 4000| 3|
Britney | 3900| 3|
Kelly | 3800| 3|
Jennifer | 3600| 3|
Renske | 3600| 3|
Trenna | 3500| 3|
Julia | 3400| 3|
Jason | 3300| 3|
Laura | 3300| 3|
Julia | 3200| 3|
Samuel | 3200| 3|
Winston | 3200| 3|
Stephen | 3200| 3|
Alexander | 3100| 3|
Alana | 3100| 3|
Jean | 3100| 3|
Curtis | 3100| 3|
Kevin | 3000| 4|
Anthony | 3000| 4|
Shelli | 2900| 4|
Timothy | 2900| 4|
Michael | 2900| 4|
Sigal | 2800| 4|
Vance | 2800| 4|
Girard | 2800| 4|
Mozhe | 2800| 4|
John | 2700| 4|
Irene | 2700| 4|
Guy | 2600| 4|
Douglas | 2600| 4|
Donald | 2600| 4|
Randall | 2600| 4|
Karen | 2500| 4|
James | 2500| 4|
Randall | 2500| 4|
Peter | 2500| 4|
Martha | 2500| 4|
Joshua | 2500| 4|
Ki | 2400| 4|
James | 2400| 4|
Hazel | 2200| 4|
Steven | 2200| 4|
TJ | 2100| 4|'Oracle > SQL' 카테고리의 다른 글
| [Oracle] EXECUTE IMMEDIATE 문 ( 동적 SQL) (1) | 2024.07.04 |
|---|---|
| [SQL] 계층형 쿼리 ( CONNECT BY ) (0) | 2024.03.05 |
| [SQL] 윈도우 함수(Window Function)의 종류(3) - 행 순서 관련 함수(FIRST_VALUE, LAST_VALUE, LAG, LEAD) (1) | 2023.04.17 |
| [SQL] 윈도우 함수(Window Function)의 종류(2) - 집계 관련 함수(SUM, MAX, MIN, AVG, COUNT) (0) | 2023.04.13 |
| [SQL] 윈도우 함수(Window Function)의 종류(1) - 순위 관련 함수(RANK, DENSE_RANK, ROW_NUMBER) (1) | 2023.04.05 |