songining
article thumbnail

WINDOW FUNCTION

- ๋ถ€๋ถ„์ ์ด๋‚˜๋งˆ ํ–‰๊ณผ ํ–‰๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ์‰ฝ๊ฒŒ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“  ํ•จ์ˆ˜. 

- ์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ํ•˜๋‚˜์˜ SQL๋ฌธ์žฅ์œผ๋กœ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. 

- WINDOW ํ•จ์ˆ˜๋Š” ๋‹ค๋ฆ„ ํ•จ์ˆ˜์™€ ๋‹ฌ๋ฆฌ ์ค‘์ฒฉํ•ด์„œ ์‚ฌ์šฉํ•˜์ง€๋Š” ๋ชปํ•˜์ง€๋งŒ, ์„œ๋ธŒ์ฟผ๋ฆฌ์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1.๊ทธ๋ฃน ๋‚ด ์ˆœ์œ„(RANK) ๊ด€๋ จ ํ•จ์ˆ˜

 - RANK, DENSE_RANK, ROW_NUMBER ํ•จ์ˆ˜

2.๊ทธ๋ฃน ๋‚ด ์ง‘๊ณ„(AGGREGATE) ๊ด€๋ จ ํ•จ์ˆ˜

 - SUM, MAX, MIN, AVG, COUNT ํ•จ์ˆ˜ 

3.๊ทธ๋ฃน ๋‚ด ํ–‰ ์ˆœ์„œ ๊ด€๋ จ ํ•จ์ˆ˜

 - FIRST_VALUE, LAST_VALUE, LAG, LEAD ํ•จ์ˆ˜ 

4.๊ทธ๋ฃน ๋‚ด ๋น„์œจ ๊ด€๋ จ ํ•จ์ˆ˜

 - CUME_DIST, PERCENT_RANK, NTILE, RATIO_TO_REPORT ํ•จ์ˆ˜

 

WINDOW FUNCTION SYNTAX

SELECT  WINDOW_FUNCTION (ARGUMENTS) OVER 

 ( [PARTITION BY ์นผ๋Ÿผ] [ORDER BY์ ˆ] [WINDOWING ์ ˆ] ) 

FROM ํ…Œ์ด๋ธ”๋ช…; 

 

RANK ํ•จ์ˆ˜

- ORDER BY๋ฅผ ํฌํ•จํ•œ QUERY ๋ฌธ์—์„œ ํŠน์ • ์นผ๋Ÿผ์— ๋Œ€ํ•œ ์ˆœ์œ„๋ฅผ ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

- ํŠน์ • ๋ฒ”์œ„(PARTITION) ๋‚ด์—์„œ ์ˆœ์œ„๋ฅผ ๊ตฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

-๋˜ํ•œ ๋™์ผํ•œ ๊ฐ’์— ๋Œ€ํ•ด์„œ๋Š” ๋™์ผํ•œ ์ˆœ์œ„๋ฅผ ๋ถ€์—ฌํ•˜๊ฒŒ ๋œ๋‹ค. 

 

์˜ˆ์ œ) SELECT JOB, ENAME, SAL,

  RANK() OVER (ORDER BY SAL DESC) ALL_RANK, -> SAL์„ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ˆœ์œ„ ๋งค๊น€

  RANK() OVER (PARTITION BY JOB ORDER BY SAL DESC) JOB_RANK -> ๊ฐ™์€ JOB๋‚ด์—์„œ SAL๋ณ„๋กœ ์ˆœ์œ„ ๋งค๊น€ 

FROM EMP;

* ๋™์ผํ•œ SAL์— ๋Œ€ํ•ด์„œ๋Š” ๊ฐ™์€ ์ˆœ์œ„ ๋ถ€์—ฌ 

* ORDER BY SAL DESC์™€ PARTITION BY JOB ์กฐ๊ฑด์˜ ์ถฉ๋Œ      ๋กœ ์ธํ•ด JOB๋ณ„๋กœ๋Š” ์ €์—ดใ„น๋˜์ง€ ์•Š๊ณ  SAL DESC๋กœ ์ •๋ ฌ๋จ. 

 

 

 

 

 

 

 

 

 

 

 

 

DENSE_RANK ํ•จ์ˆ˜

RANKํ•จ์ˆ˜์™€์˜ ์ฐจ์ด์ ์€ ๋™์ผํ•œ ์ˆœ์œ„๋ฅผ ํ•˜๋‚˜์˜ ๊ฑด์ˆ˜๋กœ ์ทจ๊ธ‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

 

์˜ˆ์ œ) SELECT JOB, ENAME, SAL,

  RANK() OVER (ORDER BY SAL DESC) RANK, 

  DENSE_RANK() OVER (ORDER BY SAL DESC) DENSE_RANK

FROM EMP;   

์•„๊นŒ์™€ ๋‹ค๋ฅด๊ฒŒ DENSE_RANK์˜ ๊ฒฝ์šฐ ๋™์ผ์ˆœ์œ„์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ๊ฑด์ˆ˜๋กœ ์ทจ๊ธ‰ํ•˜์—ฌ 2๋“ฑ ๋‹ค์Œ์ด 3๋“ฑ์ด ๋˜์—ˆ๋‹ค.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ROW_NUMBER ํ•จ์ˆ˜

ROW_NUMBER ํ•จ์ˆ˜๋Š” RANK๋‚˜ DENSE_RANK ํ•จ์ˆ˜๊ฐ€ ๋™์ผํ•œ ๊ฐ’์— ๋Œ€ํ•ด ๋™์ผํ•œ ์ˆœ์œ„๋ฅผ ๋ถ€์—ฌํ•˜๋Š”๋ฐ ๋ฐ˜ํ•ด, 

 ๋™์ผํ•œ ๊ฐ’์ด๋ผ๋„ ์œ ๋‹ˆํฌํ•œ ์ˆœ์œ„๋ฅผ ๋ถ€์—ฌํ•œ๋‹ค. 

- ๋™์ผํ•œ ๊ฐ’์˜ ์ˆœ์„œ ๊ธฐ์ค€์€ ์ •ํ•ด์ฃผ์ง€ ์•Š์•˜๋‹ค๋ฉด ๋žœ๋ค์ด๋‹ค. (ORACLE์˜ ๊ฒฝ์šฐ rowid๊ฐ€ ์ ์€ ํ–‰์ด ๋จผ์ € ๋‚˜์˜จ๋‹ค.) 

 

์˜ˆ์ œ) SELECT JOB, ENAME, SAL, RANK() OVER (ORDER BY SAL DESC) RANK,

     ROW_NUMBER() OVER (ORDER BY SAL DESC) ROW_NUMBER

FROM EMP; 

* ๋™์ผํ•œ ์ˆœ์œ„๋ฅผ ๋ฐฐ์ œํ•˜๊ธฐ ์œ„ํ•ด ์œ ๋‹ˆํฌํ•œ ์ˆœ์œ„๊ฐ€ ์ •ํ•ด์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

*  ๋งŒ์•ฝ ๋™์ผ ๊ฐ’์— ์ˆœ์„œ๊นŒ์ง€ ๊ด€๋ฆฌํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด 

ROW_NUMBER() OVER (ORDER BY SAL DESC,ENAME)๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€์ ์ธ ์ •๋ ฌ ๊ธฐ์ค€ ์ •์˜ํ•œ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

MIN ํ•จ์ˆ˜

- MIN ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ํŒŒํ‹ฐ์…˜๋ณ„ ์œˆ๋„์šฐ์˜ ์ตœ์†Œ๊ฐ’์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

์˜ˆ์ œ) SELECT MGR, ENAME, HIREDATE, SAL, 

MIN(SAL) OVER(PARTITION BY MGR ORDER BY HIREDATE RANGE UNBOUNDED PRECEDING ) AS MGR_MIN

FROM EMP; 

+) RANGE UNBOUNDED PRECEDING :  ํ˜„์žฌ ํ–‰์„ ๊ธฐ์ค€์œผ๋กœ ํŒŒํ‹ฐ์…˜ ๋‚ด์˜ ์ฒซ๋ฒˆ์งธ ํ–‰๊นŒ์ง€์˜ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•œ๋‹ค. 

 

SUM ํ•จ์ˆ˜

ํŒŒํ‹ฐ์…˜๋ณ„ ์œˆ๋„์šฐ์˜ ํ•ฉ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

์˜ˆ์ œ)

SELECT MGR, ENAME, SAL, SUM(SAL) OVER (PARTITION BY MGR ORDER BY SAL RANGE UNBOUNDED PRECEDING

FROM EMP; 

 * MGR ๋ณ„๋กœ SAL ๊ฐ’์„ ๊ณ„์†ํ•ด์„œ ๋ˆ„์ ํ•œ๋‹ค. 

* ๋‹จ, ๊ฐ’์ด ๊ฐ™์„ ๊ฒฝ์šฐ์—๋Š” ๋™์ผํ•œ ์ˆœ์œ„๋กœ ์ทจ๊ธ‰ํ•˜์—ฌ ํ•œ๋ฒˆ์— ๋”ํ•ด์ค€๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

 

AVG ํ•จ์ˆ˜

AVG ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ํ†ต๊ณ„๊ฐ’์„ ๊ตฌํ•  ์ˆ˜ ์žˆ์Œ. 

 

์˜ˆ์ œ)

SELECT MGR, ENAME, HIREDATE, SAL, 

     ROUND(AVG(SAL) OVER (PARTITION BY MGR ORDER BY HIREDATE ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)

FROM EMP;

* ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING 

์— ์˜ํ•ด ์œ„์˜ ํ–‰๊ณผ ์•„๋ž˜ํ–‰๊ณผ ํ•จ๊ป˜ ํ‰๊ท ๊ฐ’์„ ์ง‘๊ณ„ํ•œ๋‹ค.

(์•ž์ด๋‚˜ ๋’ค์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋ฉด ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ๋งŒ) 

 

 

 

 

 

 

 

 

 

 

 

 

COUNT ํ•จ์ˆ˜

์˜ˆ์ œ)

SELECT ENAME,SAL, COUNT(*) OVER (ORDER BY SAL RANGE BETWEEN 50 PRECEDING AND 150 FOLLOWING) AS MOV_COUNT 

FROM EMP;

* RANGE BETWEEN 50 PRECEDING AND 150 FOLLOWING 

์— ์˜ํ•ด SAL๊ฐ€ ํ˜„์žฌ ๋ฐ์ดํ„ฐ ๊ธฐ์ค€ -50 ~+150 ๊ธฐ์ค€์— ๋งž๋Š”์ง€ ๊ฒ€์‚ฌํ•œ ํ›„ ์—ฐ์‚ฐํ•œ๋‹ค. (PARTITION BY ์‚ฌ์šฉ ์•ˆํ–ˆ์œผ๋ฏ€๋กœ ๋ชจ๋“  ๊ฑด์ˆ˜์— ๋Œ€ํ•ด ํƒ์ƒ‰ํ•œ๋‹ค.) 

*  ** ํ‘œ์‹œ์— ์žˆ๋Š” ๊ฐ’์„ ์˜ˆ์‹œ๋กœ ๋“ค์—ˆ์„ ๋•Œ 1100-50์ธ 1050๋ถ€ํ„ฐ 1100+150์ธ 1250 ์•ˆ์— ํฌํ•จ๋˜๋Š” SAL๋ฅผ ์ „๋ถ€ ์„ธ์ค€๋‹ค. ์ฆ‰ 3์ด๋‹ค. (1100,1250,1250) 

 

 

 

 

 

 

 

 

 

FIRST_VALUE ํ•จ์ˆ˜

- ๊ฐ€์žฅ ๋จผ์ € ๋‚˜์˜จ ๊ฐ’์„ ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. 

 

์˜ˆ์ œ) 

SELECT DEPTNO, ENAME, SAL, FIRST_VALUE(ENAME) OVER ( PARTITION BY DEPTNO ORDER BY SAL DESC, ENAME ASC ROWS UNBOUNDED PRECEDING ) AS RICH_EMP

FROM EMP; 

 * DEPTNO ๋ณ„๋กœ ๊ฐ€์žฅ ๋จผ์ € ๋‚˜์˜จ ๊ฐ’์„ ์ถœ๋ ฅํ•œ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

LAG ํ•จ์ˆ˜

- LAG ํ•จ์ˆ˜๋Š” 3๊ฐœ์˜ ARGUMENTS ๊นŒ์ง€ ์‚ฌ์šฉํ•  ์ˆ˜  ์žˆ๋Š”๋ฐ, ๋‘๋ฒˆ์งธ ์ธ์ž๋Š” ๋ช‡๋ฒˆ์งธ ์•ž์˜ ํ–‰์„ ๊ฐ€์ ธ์˜ฌ์ง€ ๊ฒฐ์ •ํ•˜๊ณ (DEFAULT๋ผ๋ฉด 1) , ์„ธ๋ฒˆ์งธ ์ธ์ž๋Š” ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ€์ ธ์˜ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ NULL์ด ๋“ค์–ด์˜ค๋ฏ€๋กœ ์ด๋•Œ ๋‹ค๋ฅธ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ”์ค„ ์ˆ˜ ์žˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ  NVI ๋˜๋Š” ISNULL๊ณผ ๊ฐ™๋‹ค. 

 

์˜ˆ์ œ)

SELECT ENAME, HIREDATE, SAL, LAG(SAL, 2, 0) OVER (ORDER BY HIREDATE) AS PREV_SAL
FROM EMP
WHERE JOB = 'SALESMAN' ;

 

LEAD ํ•จ์ˆ˜

- ๋ช‡๋ฒˆ์งธ ์•„๋ž˜์˜ ํ–‰์„ ๊ฐ€์ ธ์˜ฌ ์ง€ ๊ฒฐ์ •ํ•œ๋‹ค. (LAG์™€ ๋ฐ˜๋Œ€) 

 

RATIO_TO_REPORT ํ•จ์ˆ˜

- ํŒŒํ‹ฐ์…˜ ๋‚ด ์ „์ฒด SUM(์นผ๋Ÿผ)๊ฐ’์— ๋Œ€ํ•œ ํ–‰๋ณ„ ์นผ๋Ÿผ ๊ฐ’์˜ ๋ฐฑ๋ถ„์œจ์„ ์†Œ์ˆ˜์ ์œผ๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฒฐ๊ณผ๊ฐ’์€ 0< X <=1 ์˜ ๋ฒ”์œ„๋ฅผ ๊ฐ€์ง„๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐœ๋ณ„ RATIO์˜ ํ•ฉ์„ ๊ตฌํ•˜๋ฉด 1์ด ๋œ๋‹ค. 

 

์˜ˆ์ œ) 

SELECT ENAME, SAL,
ROUND(RATIO_TO_REPORT(SAL) OVER (), 2) AS R_R
FROM EMP
WHERE JOB = 'SALESMAN';

PERCENT_RANK ํ•จ์ˆ˜

- ์ œ์ผ ๋จผ์ € ๋‚˜์˜ค๋Š” ๊ฒƒ์„ 0์œผ๋กœ, ์ œ์ผ ๋Šฆ๊ฒŒ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ 1์œผ๋กœ ํ•˜์—ฌ, ๊ฐ’์ด ์•„๋‹Œ ํ–‰์˜ ์ˆœ์„œ๋ณ„ ๋ฐฑ๋ถ„์œจ์„ ๊ตฌํ•œ๋‹ค. 

๊ฒฐ๊ณผ๊ฐ’์€ 0<X<=1์˜ ๋ฒ”์œ„๋ฅผ ๊ฐ€์ง„๋‹ค. 

 

์˜ˆ์ œ) SELECT DEPTNO, ENAME, SAL, PERCENT_RANK() OVER
(PARTITION BY DEPTNO ORDER BY SAL DESC) AS P_R
 FROM EMP;

  

* ORDER BY SAL์— ์˜ํ•ด ๋งŒ์•ฝ SAL์˜ ๊ฐ’์ด ๊ฐ™๋‹ค๋ฉด ๊ฐ™์€ ์ˆœ์œ„๋กœ ์ทจ๊ธ‰ํ•œ๋‹ค. (SAL์ดํ›„์— ๋‹ค๋ฅธ ์ •๋ ฌ๊ธฐ์ค€์ด ์—†์œผ๋ฏ€๋กœ) 

 

 

 

 

 

 

 

 

 

 

 

 

 

CUME_DIST ํ•จ์ˆ˜

- ํŒŒํ‹ฐ์…˜๋ณ„ ์ „์ฒด ๊ฑด์ˆ˜์—์„œ ํ˜„์žฌ ํ–‰๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฑด์ˆ˜์— ๋Œ€ํ•œ ๋ˆ„์  ๋ฐฑ๋ถ„์œจ์„ ๊ตฌํ•œ๋‹ค.

๊ฒฐ๊ณผ๊ฐ’์€ 0< X <=1 ์˜ ๋ฒ”์œ„๋ฅผ ๊ฐ€์ง„๋‹ค. 

 

์˜ˆ์ œ) SELECT DEPTNO, ENAME, SAL, CUME_DIST() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC)
AS CUME_DIST
FROM EMP;

* DEPTNO 20์ธ ๊ฒฝ์šฐ ์ „์ฒด ์ด 5๊ฑด์ด๋ฏ€๋กœ ํ•˜๋‚˜๋‹น 0.2 ๋‹จ์œ„์˜ ๊ฐ„๊ฒฉ์„ ๊ฐ€์ง„๋‹ค. 

* CUME_DIST์˜ ๊ฒฝ์šฐ ๋‹ค๋ฅธ WINDOW ํ•จ์ˆ˜์™€ ๋‹ฌ๋ฆฌ ๋™์ผ์ˆœ์„œ๋ฉด ๋’ค ํ–‰์˜ ํ•จ์ˆ˜ ๊ฒฐ๊ณผ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ํ•œ๋‹ค. 

(๊ทธ๋ž˜์„œ ์ค‘๋ณต์— ๋Œ€ํ•ด ํ•œ๊ฑด์œผ๋กœ ์น˜์ง€ ์•Š๋Š”๊ฑด๊ฐ€?) 

 

 

 

 

 

 

 

 

 

 

 

NTILE ํ•จ์ˆ˜

- ํŒŒํ‹ฐ์…˜๋ณ„ ์ „์ฒด ๊ฑด์ˆ˜๋ฅผ ARGUMENT ๊ฐ’์œผ๋กœ N๋“ฑ๋ถ„ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์ œ)

SELECT ENAEM, SAL, NTILE(4) OVER (ORDER BY SAL DESC) AS QUAR_TILE 

FROM EMP; 

 ์ด 14๋ช…์˜ ํŒ€์›์„ 4๊ฐœ์˜ ์กฐ๋กœ ๋‚˜๋ˆ„์–ด์•ผ ํ•˜๋ฏ€๋กœ 

4+4+3+3์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ํ•ฉ๋ฆฌ์ ์ด๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

์ถœ์ฒ˜ : SQL ์ „๋ฌธ๊ฐ€ ๊ฐ€์ด๋“œ