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 ์ ๋ฌธ๊ฐ ๊ฐ์ด๋
'SQLD' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๊ณผ๋ชฉII SQL ๊ธฐ๋ณธ ๋ฐ ํ์ฉ 2์ฅ - 7์ DCL (0) | 2021.05.25 |
---|---|
๊ณผ๋ชฉII SQL ๊ธฐ๋ณธ ๋ฐ ํ์ฉ 2์ฅ - 5์ GROUP FUNCTION (0) | 2021.05.25 |
๊ณผ๋ชฉII SQL ๊ธฐ๋ณธ ๋ฐ ํ์ฉ 2์ฅ - 4์ ์๋ธ์ฟผ๋ฆฌ (0) | 2021.05.25 |
๊ณผ๋ชฉII SQL ๊ธฐ๋ณธ ๋ฐ ํ์ฉ 2์ฅ - 3์ ๊ณ์ธตํ ์ง์์ ์ ํ ์กฐ์ธ (0) | 2021.05.24 |
๊ณผ๋ชฉ II SQL ๊ธฐ๋ณธ ๋ฐ ํ์ฉ 2์ฅ - 2์ ์งํฉ ์ฐ์ฐ์ (0) | 2021.05.24 |