์๋์ฐ ํจ์ (Window Function)
ํ์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ง ์๊ณ ๊ฐ ํ์ ๋ํ์ฌ ํ๋ฒํธ, ์์, ์ด์ ํ, ๋ค์ ํ ๋น๊ต ๋ฑ์ ์ํํ๋ ํจ์
์๋์ฐ ํจ์ ๋ฌธ๋ฒ ๊ตฌ์กฐ
์๋์ฐ ํจ์ OVER (
PARTITION BY ์ปฌ๋ผ -- ๊ทธ๋ฃน ๊ธฐ์ค
ORDER BY ์ปฌ๋ผ -- ์ ๋ ฌ ๊ธฐ์ค
ROWS BETWEEN ... -- ํ๋ ์ ์ง์ ์ต์
)
SQL
๋ณต์ฌ
์ฃผ์ ์๋์ฐ ํจ์
ํจ์ ์ด๋ฆ | ์ค๋ช
|
ROW_NUMBER() | ํํฐ์
๋ด ์๋ฒ ๋ถ์ฌ (์ค๋ณต ์์ด ๊ณ ์ ) |
RANK() | ๋์ผ ๊ฐ์ ๋์ผ ์์, ๋ค์ ์์๋ ๊ฑด๋๋ |
DENSE_RANK() | ๋์ผ ๊ฐ์ ๋์ผ ์์, ๋ค์ ์์๋ ๊ฑด๋๋ฐ์ง ์์ |
NTILE(N) | ํํฐ์
์ N๊ฐ์ ๊ทธ๋ฃน์ผ๋ก ๋๋์ด ๋ฒํธ ๋ถ์ฌ |
LAG(col, n, def) | nํ ์ด์ ์ ๊ฐ ๋ฐํ (์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ) |
LEAD(col, n, def) | nํ ์ดํ์ ๊ฐ ๋ฐํ (์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ) |
FIRST_VALUE() | ํํฐ์
๋ด ์ฒซ ๋ฒ์งธ ๊ฐ ๋ฐํ |
LAST_VALUE() | ํํฐ์
๋ด ๋ง์ง๋ง ๊ฐ ๋ฐํ |
SUM() | ๋์ ํฉ๊ณ |
AVG() | ๋์ ํ๊ท |
MAX() | ๋์ ์ต๋๊ฐ |
MIN() | ๋์ ์ต์๊ฐ |
COUNT() | ๋์ ๊ฐ์ |
ํ๋ ์ ์ง์ ์ต์ ํค์๋
ํค์๋ | ์๋ฏธ | ์์ ์ค๋ช
|
UNBOUNDED PRECEDING | ์ฒซ ๋ฒ์งธ ํ๋ถํฐ ์์ | ์ฐฝ์ ์์ ์ง์ ์ ํ
์ด๋ธ ๋๋ ํํฐ์
์ ๋งจ ์ฒ์ ํ์ผ๋ก ์ง์ |
n PRECEDING | ํ์ฌ ํ์์ nํ ์ด์ ๋ถํฐ ์์ | ์: 2 PRECEDING โ ํ์ฌ๋ณด๋ค 2ํ ์์์ ์์ |
CURRENT ROW | ํ์ฌ ํ๋ถํฐ ์์ ๋๋ ๋ | ์๋์ฐ ๊ฒฝ๊ณ๋ฅผ ํ์ฌ ํ์ผ๋ก ์ง์ |
n FOLLOWING | ํ์ฌ ํ์์ nํ ์ดํ๊น์ง ํฌํจ | ์: 1 FOLLOWING โ ํ์ฌ๋ณด๋ค 1ํ ๋ค๊น์ง ํฌํจ |
UNBOUNDED FOLLOWING | ๋ง์ง๋ง ํ๊น์ง ํฌํจ | ์ฐฝ์ ๋ ์ง์ ์ ํํฐ์
๋๋ ์ ์ฒด ๋ฐ์ดํฐ์ ๋ง์ง๋ง ํ์ผ๋ก ์ง์ |
ROW_NUMBER()
๊ฐ ํํฐ์
๋ณ ์ ๋ ฌ ๊ธฐ์ค์ ๋ฐ๋ผ ๊ณ ์ ํ ํ๋ฒํธ๋ฅผ ๋ถ์ฌํ๋ ํจ์
SELECT emp_no
,name
,dept_no
,salary
,ROW_NUMBER() OVER (
PARTITION BY dept_no
ORDER BY salary DESC
) AS '๋ถ์๋ณ ๊ธ์ฌ์๋ฒ'
FROM employees;
SQL
๋ณต์ฌ
RANK( )
์ค๋ณต๋ ์์๋ ๊ฑด๋๋ฐ๋ ์์๋ฅผ ๊ตฌํ๋ ํจ์
SELECT emp_no
,name
,dept_no
,salary
,RANK() OVER (
PARTITION BY dept_no
ORDER BY salary DESC
) AS '๋ถ์๋ณ ๊ธ์ฌ์์'
FROM employees;
SQL
๋ณต์ฌ
DENSE_RANK( )
๊ณต๋ ์์๋ฅผ ๋ถ์ฌํ๊ณ , ์ค๋ณต๋ ์์๋ฅผ ๊ฑด๋๋ฐ์ง ์๊ณ ์์๋ฅผ ๊ตฌํ๋ ํจ์
SELECT emp_no
,name
,dept_no
,salary
,DENSE_RANK() OVER (
PARTITION BY dept_no
ORDER BY salary DESC
) AS '๋ถ์๋ณ ๊ธ์ฌ์์'
FROM employees;
SQL
๋ณต์ฌ
NTILE( n )
์ ๋ ฌ๋ ๊ฒฐ๊ณผ๋ฅผ n๊ฐ์ ๋์ผํ ํฌ๊ธฐ ๊ทธ๋ฃน์ผ๋ก ๋๋์ด์ ๊ทธ๋ฃน ๋ฒํธ๋ฅผ ๋ถ์ฌํ๋ ํจ์
SELECT emp_no
,name
,salary
,NTILE(4) OVER (
ORDER BY salary DESC
) AS '๊ธ์ฌ ๋ถ์'
FROM employees;
SQL
๋ณต์ฌ
LAG( )
ํ์ฌ ํ๋ณด๋ค nํ ์ด์ ๊ฐ์ ๊ฐ์ ธ์ค๋ ํจ์
LAG( ์ปฌ๋ผ, nํ, ๊ธฐ๋ณธ๊ฐ )
SQL
๋ณต์ฌ
SELECT emp_no
,name
,salary
,LAG( salary, 1, 0 ) OVER (ORDER BY emp_no) AS '1ํ ์ด์ ์ฌ์ ๊ธ์ฌ'
FROM employees;
SQL
๋ณต์ฌ
LEAD( )
ํ์ฌ ํ๋ณด๋ค nํ ๋ค์ ๊ฐ์ ๊ฐ์ ธ์ค๋ ํจ์
LEAD( ์ปฌ๋ผ, nํ, ๊ธฐ๋ณธ๊ฐ )
SQL
๋ณต์ฌ
SELECT emp_no
,name
,salary
,LEAD( salary, 1, 0 ) OVER (ORDER BY emp_no) AS '1ํ ๋ค์ ์ฌ์ ๊ธ์ฌ'
FROM employees;
SQL
๋ณต์ฌ
FIRST_VALUE()
์๋์ฐ ๋ด์ ์ฒซ๋ฒ์งธ ๊ฐ์ ๋ฐํํ๋ ํจ์
SELECT emp_no
,name
,salary
,dept_no
,FIRST_VALUE(salary)
OVER (
PARTITION BY dept_no
ORDER BY emp_no
) AS '์ฒซ๋ฒ์งธ ์ฌ์์ ๊ธ์ฌ'
FROM employees;
SQL
๋ณต์ฌ
LAST_VALUE()
์๋์ฐ ๋ด์ ๋ง์ง๋ง ๊ฐ์ ๋ฐํํ๋ ํจ์
SELECT emp_no
,name
,salary
,dept_no
,LAST_VALUE(salary)
OVER (
PARTITION BY dept_no
ORDER BY emp_no
ROWS BETWEEN
UNBOUNDED PRECEDING
AND
UNBOUNDED FOLLOWING
) AS '๋ง์ง๋ง ์ฌ์์ ๊ธ์ฌ'
FROM employees;
SQL
๋ณต์ฌ
SUM(), AVG(), MIN(), MAX(), COUNT()
์๋์ฐ ํ๋ ์ ๋ด์์ ์ง๊ณ๋ฅผ ๊ตฌํ๋ ํจ์
SELECT emp_no
,name
,salary
,dept_no
,SUM(salary) OVER (
PARTITION BY dept_no
ORDER BY salary ASC
ROWS BETWEEN
1 PRECEDING
AND
1 FOLLOWING
) AS '1ํ ์๋ค ํฉ๊ณ'
,AVG(salary) OVER (
PARTITION BY dept_no
ORDER BY salary ASC
ROWS BETWEEN
UNBOUNDED PRECEDING
AND
CURRENT ROW
) AS '์ฒซํ~ํ์ฌํ ํ๊ท '
FROM employees;
SQL
๋ณต์ฌ