Search

MySQL ์œˆ๋„์šฐํ•จ์ˆ˜

MySQL ์œˆ๋„์šฐ ํ•จ์ˆ˜ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ธฐ!

์ด ์˜์ƒ์€ MySQL์—์„œ **์œˆ๋„์šฐ ํ•จ์ˆ˜(Window Function)**๋ฅผ ์–ด๋–ป๊ฒŒ ์“ฐ๋Š”์ง€, ์ข…๋ฅ˜๋ณ„ ํŠน์ง•๊ณผ ๋ฌธ๋ฒ•, ๊ทธ๋ฆฌ๊ณ  ์‹ค์Šต ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ค๋‹ˆ๋‹ค. ์œˆ๋„์šฐ ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์ง€ ์•Š๊ณ ๋„ ๊ฐ ํ–‰๋ณ„๋กœ ์ˆœ์œ„, ์ด์ „/๋‹ค์Œ ํ–‰ ๋น„๊ต, ๋ˆ„์  ํ•ฉ๊ณ„ ๋“ฑ์„ ์‰ฝ๊ฒŒ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์•„์ฃผ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ด์—์š”.

๋ชฉ์ฐจ

โ€ข
์œˆ๋„์šฐ ํ•จ์ˆ˜ ๊ฐœ๋…๊ณผ ๊ธฐ๋ณธ ๋ฌธ๋ฒ• [00:00:14]
โ€ข
์ฃผ์š” ์œˆ๋„์šฐ ํ•จ์ˆ˜ ์ข…๋ฅ˜์™€ ํŠน์ง• [00:01:27]
โ€ข
ํ”„๋ ˆ์ž„ ์ง€์ • ์˜ต์…˜ ์ดํ•ดํ•˜๊ธฐ (๋ฒ”์œ„ ์„ค์ •) [00:04:28]
โ€ข
์‹ค์Šต: ๋กœ์šฐ ๋„˜๋ฒ„ (ROW_NUMBER) ํ•จ์ˆ˜ ์‚ฌ์šฉ๋ฒ• [00:11:04]
โ€ข
๋žญํฌ(RANK)์™€ ๋Œ„์Šค ๋žญํฌ(DENSE_RANK) ์ฐจ์ด [00:16:18]
โ€ข
์—”ํƒ€์ผ(NTILE) ํ•จ์ˆ˜๋กœ ๋ฐ์ดํ„ฐ ๊ทธ๋ฃน ๋‚˜๋ˆ„๊ธฐ [00:18:52]
โ€ข
์ด์ „ ํ–‰ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ: ๋ ˆ๊ทธ(LAG), ๋‹ค์Œ ํ–‰ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ: ๋ฆฌ๋“œ(LEAD) [00:21:18]
โ€ข
์ฒซ ๋ฒˆ์งธ ๊ฐ’๊ณผ ๋งˆ์ง€๋ง‰ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ: ํผ์ŠคํŠธ ๋ฐธ๋ฅ˜(FIRST_VALUE), ๋ผ์ŠคํŠธ ๋ฐธ๋ฅ˜(LAST_VALUE) [00:23:20]
โ€ข
์œˆ๋„์šฐ ํ•จ์ˆ˜๋กœ ๋ˆ„์  ํ•ฉ๊ณ„, ํ‰๊ท  ๋“ฑ ์ง‘๊ณ„ ํ•จ์ˆ˜ ํ™œ์šฉํ•˜๊ธฐ [00:34:09]
โ€ข
๋งˆ๋ฌด๋ฆฌ ์ •๋ฆฌ ๋ฐ ์š”์•ฝ [00:39:41]

์œˆ๋„์šฐ ํ•จ์ˆ˜ ๊ฐœ๋…๊ณผ ๊ธฐ๋ณธ ๋ฌธ๋ฒ• [00:00:14]

์œˆ๋„์šฐ ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์ง€ ์•Š๊ณ ๋„ ๊ฐ ํ–‰์— ๋Œ€ํ•ด ์ˆœ์œ„(๋žญํฌ), ํ–‰ ๋ฒˆํ˜ธ, ์ด์ „ ํ–‰๊ณผ ๋‹ค์Œ ํ–‰ ๋น„๊ต ๊ฐ™์€ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
๊ธฐ๋ณธ ๋ฌธ๋ฒ•์€ ํ•จ์ˆ˜๋ช… ๋’ค์—ย OVERย ํ‚ค์›Œ๋“œ๋ฅผ ์“ฐ๊ณ , ๊ทธ ์•ˆ์—ย PARTITION BYย (๊ทธ๋ฃน ๊ธฐ์ค€),ย ORDER BYย (์ •๋ ฌ ๊ธฐ์ค€), ๊ทธ๋ฆฌ๊ณ ย ROWS BETWEENย (๋ฒ”์œ„ ์ง€์ •) ์˜ต์…˜์„ ๋„ฃ์–ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด,
ROW_NUMBER() OVER (PARTITION BY ๋ถ€์„œ ORDER BY ๊ธ‰์—ฌ DESC)
SQL
๋ณต์‚ฌ
๋Š” ๋ถ€์„œ๋ณ„๋กœ ๊ธ‰์—ฌ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ ํ›„ ๊ฐ ํ–‰์— ๊ณ ์œ ํ•œ ๋ฒˆํ˜ธ๋ฅผ ๋ถ™์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ์œˆ๋„์šฐ ํ•จ์ˆ˜ ์ข…๋ฅ˜์™€ ํŠน์ง• [00:01:27]

1.
ROW_NUMBER(): ๊ฐ ๊ทธ๋ฃน(ํŒŒํ‹ฐ์…˜) ๋‚ด์—์„œ ํ–‰ ๋ฒˆํ˜ธ๋ฅผ ๋งค๊น๋‹ˆ๋‹ค.
2.
RANK(): ์ˆœ์œ„๋ฅผ ๋งค๊ธฐ๋Š”๋ฐ, ๋™์ ์ด ์žˆ์œผ๋ฉด ๋‹ค์Œ ์ˆœ์œ„๋ฅผ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.
โ€ข
์˜ˆ: 1๋“ฑ, 2๋“ฑ, 2๋“ฑ, 2๋“ฑ ๋‹ค์Œ์€ 5๋“ฑ
3.
DENSE_RANK(): ๋™์ ์ด ์žˆ์–ด๋„ ์ˆœ์œ„๋ฅผ ๊ฑด๋„ˆ๋›ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
โ€ข
์˜ˆ: 1๋“ฑ, 2๋“ฑ, 2๋“ฑ, 2๋“ฑ ๋‹ค์Œ์€ 3๋“ฑ
4.
NTILE(n): ๋ฐ์ดํ„ฐ๋ฅผ n๊ฐœ์˜ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„๊ณ  ๊ฐ ๊ทธ๋ฃน์— ๋ฒˆํ˜ธ๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.
โ€ข
์˜ˆ: 30๋ช…์„ 4๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„๋ฉด ๊ฐ ๊ทธ๋ฃน์— 1~4 ๋ฒˆํ˜ธ ๋ถ€์—ฌ
5.
LAG(column, n, default): ํ˜„์žฌ ํ–‰ ๊ธฐ์ค€์œผ๋กœ ์ด์ „ nํ–‰์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๊ฐ’์ด ์—†์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’(default) ์‚ฌ์šฉ
6.
LEAD(column, n, default): ํ˜„์žฌ ํ–‰ ๊ธฐ์ค€์œผ๋กœ ๋‹ค์Œ nํ–‰์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
7.
FIRST_VALUE() / LAST_VALUE(): ๊ทธ๋ฃน ๋‚ด ์ฒซ ๋ฒˆ์งธ / ๋งˆ์ง€๋ง‰ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ

ํ”„๋ ˆ์ž„ ์ง€์ • ์˜ต์…˜ ์ดํ•ดํ•˜๊ธฐ (๋ฒ”์œ„ ์„ค์ •) [00:04:28]

์œˆ๋„์šฐ ํ•จ์ˆ˜๋Š”ย ROWS BETWEENย ์˜ต์…˜์œผ๋กœ ์ง‘๊ณ„ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์–ด์š”.
โ€ข
UNBOUNDED PRECEDING: ๊ฐ€์žฅ ์ฒซ ํ–‰๋ถ€ํ„ฐ
โ€ข
CURRENT ROW: ํ˜„์žฌ ํ–‰๊นŒ์ง€
โ€ข
N PRECEDING: ํ˜„์žฌ ํ–‰์—์„œ Nํ–‰ ์ด์ „๊นŒ์ง€
โ€ข
N FOLLOWING: ํ˜„์žฌ ํ–‰์—์„œ Nํ–‰ ์ดํ›„๊นŒ์ง€
โ€ข
UNBOUNDED FOLLOWING: ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ํ–‰๊นŒ์ง€
์˜ˆ๋ฅผ ๋“ค์–ด,
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
SQL
๋ณต์‚ฌ
๋Š” ์ฒซ ํ–‰๋ถ€ํ„ฐ ํ˜„์žฌ ํ–‰๊นŒ์ง€ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ์ด ๋ฒ”์œ„ ๋‚ด์—์„œ ํ•ฉ๊ณ„๋‚˜ ํ‰๊ท ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

์‹ค์Šต: ๋กœ์šฐ ๋„˜๋ฒ„ (ROW_NUMBER) ํ•จ์ˆ˜ ์‚ฌ์šฉ๋ฒ• [00:11:04]

โ€ข
๋ถ€์„œ๋ณ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃน(ํŒŒํ‹ฐ์…˜)ํ•˜๊ณ  ๊ธ‰์—ฌ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ๋’ค, ๊ฐ ํ–‰์— ์ˆœ๋ฒˆ์„ ๋ถ™์ž…๋‹ˆ๋‹ค.
โ€ข
๊ฒฐ๊ณผ: ๋ถ€์„œ๋ณ„๋กœ ๊ธ‰์—ฌ๊ฐ€ ๋†’์€ ์ˆœ์„œ๋Œ€๋กœ 1, 2, 3... ๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ ธ์š”.
SELECT ROW_NUMBER() OVER (PARTITION BY ๋ถ€์„œ ORDER BY ๊ธ‰์—ฌ DESC) AS ์ˆœ๋ฒˆ, ์ด๋ฆ„, ๊ธ‰์—ฌ FROM ํ…Œ์ด๋ธ”;
SQL
๋ณต์‚ฌ

๋žญํฌ(RANK)์™€ ๋Œ„์Šค ๋žญํฌ(DENSE_RANK) ์ฐจ์ด [00:16:18]

โ€ข
RANK(): ๋™์ ์ด ์žˆ์œผ๋ฉด ๋‹ค์Œ ์ˆœ์œ„๋ฅผ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.์˜ˆ) 1, 2, 2, 2, 5
โ€ข
DENSE_RANK(): ๋™์ ์ด ์žˆ์–ด๋„ ์ˆœ์œ„๋ฅผ ๊ฑด๋„ˆ๋›ฐ์ง€ ์•Š๊ณ  ์—ฐ์†์œผ๋กœ ๋งค๊น๋‹ˆ๋‹ค.์˜ˆ) 1, 2, 2, 2, 3
๋™์  ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ๋‹ค๋ฅด๋‹ˆ, ์›ํ•˜๋Š” ๊ฒฐ๊ณผ์— ๋งž๊ฒŒ ์„ ํƒํ•˜์„ธ์š”!

์—”ํƒ€์ผ(NTILE) ํ•จ์ˆ˜๋กœ ๋ฐ์ดํ„ฐ ๊ทธ๋ฃน ๋‚˜๋ˆ„๊ธฐ [00:18:52]

โ€ข
๋ฐ์ดํ„ฐ๋ฅผ N๊ฐœ์˜ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„๊ณ  ๊ฐ ๊ทธ๋ฃน์— ๋ฒˆํ˜ธ๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.
โ€ข
์˜ˆ: 30๋ช…์„ 4๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„๋ฉด 1~4๊นŒ์ง€ ๋ฒˆํ˜ธ๊ฐ€ ๋ถ€์—ฌ๋˜๊ณ , ๊ฐ ๊ทธ๋ฃน์€ ๋น„์Šทํ•œ ํฌ๊ธฐ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.
SELECT NTILE(4) OVER (ORDER BY ๊ธ‰์—ฌ DESC) AS ๊ทธ๋ฃน๋ฒˆํ˜ธ, ์ด๋ฆ„, ๊ธ‰์—ฌ FROM ํ…Œ์ด๋ธ”;
SQL
๋ณต์‚ฌ

์ด์ „ ํ–‰ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ: ๋ ˆ๊ทธ(LAG), ๋‹ค์Œ ํ–‰ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ: ๋ฆฌ๋“œ(LEAD) [00:21:18]

โ€ข
LAG(): ํ˜„์žฌ ํ–‰ ๊ธฐ์ค€์œผ๋กœ ์ด์ „ ํ–‰์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
โ€ข
LEAD(): ํ˜„์žฌ ํ–‰ ๊ธฐ์ค€์œผ๋กœ ๋‹ค์Œ ํ–‰์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
โ€ข
๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์–ด์„œ, ์ด์ „/๋‹ค์Œ ํ–‰์ด ์—†์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์ด ์ถœ๋ ฅ๋ผ์š”.
์˜ˆ)
LAG(๊ธ‰์—ฌ, 1, 0) OVER (ORDER BY ์‚ฌ์›๋ฒˆํ˜ธ)
SQL
๋ณต์‚ฌ
๋Š” ์ด์ „ ํ–‰ ๊ธ‰์—ฌ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์—†์œผ๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ ๊ฐ’๊ณผ ๋งˆ์ง€๋ง‰ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ: ํผ์ŠคํŠธ ๋ฐธ๋ฅ˜(FIRST_VALUE), ๋ผ์ŠคํŠธ ๋ฐธ๋ฅ˜(LAST_VALUE) [00:23:20]

โ€ข
FIRST_VALUE(): ๊ทธ๋ฃน ๋‚ด ์ฒซ ๋ฒˆ์งธ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
โ€ข
LAST_VALUE(): ๊ทธ๋ฃน ๋‚ด ๋งˆ์ง€๋ง‰ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
โ€ข
๊ทธ๋ฃน ๊ธฐ์ค€๊ณผ ์ •๋ ฌ ๊ธฐ์ค€์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
์˜ˆ) ๋ถ€์„œ๋ณ„ ์ฒซ ๋ฒˆ์งธ ๊ธ‰์—ฌ
FIRST_VALUE(๊ธ‰์—ฌ) OVER (PARTITION BY ๋ถ€์„œ ORDER BY ์‚ฌ์›๋ฒˆํ˜ธ)
SQL
๋ณต์‚ฌ

์œˆ๋„์šฐ ํ•จ์ˆ˜๋กœ ๋ˆ„์  ํ•ฉ๊ณ„, ํ‰๊ท  ๋“ฑ ์ง‘๊ณ„ ํ•จ์ˆ˜ ํ™œ์šฉํ•˜๊ธฐ [00:34:09]

โ€ข
์œˆ๋„์šฐ ํ•จ์ˆ˜ ์•ˆ์—์„œย SUM(),ย AVG(),ย MIN(),ย MAX(),ย COUNT()ย ๊ฐ™์€ ์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ์“ธ ์ˆ˜ ์žˆ์–ด์š”.
โ€ข
ํ”„๋ ˆ์ž„ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•ด ๋ˆ„์  ํ•ฉ๊ณ„๋‚˜ ํ‰๊ท ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ) ํ˜„์žฌ ํ–‰๊นŒ์ง€ ๊ธ‰์—ฌ ๋ˆ„์  ํ•ฉ๊ณ„
SUM(๊ธ‰์—ฌ) OVER (ORDER BY ์‚ฌ์›๋ฒˆํ˜ธ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
SQL
๋ณต์‚ฌ

๋งˆ๋ฌด๋ฆฌ ์ •๋ฆฌ ๋ฐ ์š”์•ฝ [00:39:41]

โ€ข
์œˆ๋„์šฐ ํ•จ์ˆ˜๋Š” ๊ทธ๋ฃนํ•‘ ์—†์ด๋„ ๊ฐ ํ–‰๋ณ„๋กœ ์ˆœ์œ„, ๋ˆ„์ ํ•ฉ, ์ด์ „/๋‹ค์Œ ํ–‰ ๋น„๊ต ๋“ฑ ๋‹ค์–‘ํ•œ ๋ถ„์„์ด ๊ฐ€๋Šฅํ•ด์š”.
โ€ข
ํ•ต์‹ฌ์€ย OVER()ย ์•ˆ์—ย PARTITION BYย (๊ทธ๋ฃน ๊ธฐ์ค€),ย ORDER BYย (์ •๋ ฌ ๊ธฐ์ค€),ย ROWS BETWEENย (๋ฒ”์œ„ ์ง€์ •)์„ ์ ์ ˆํžˆ ์“ฐ๋Š” ๊ฒƒ!
โ€ข
์‹ค์Šต์„ ํ†ตํ•ด ์ง์ ‘ ์จ๋ณด๋ฉด ํ›จ์”ฌ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์œˆ๋„์šฐ ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ ๋ถ„์„๊ณผ ๋ณด๊ณ ์„œ ์ž‘์„ฑ์— ๋งค์šฐ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์ด ์˜์ƒ์œผ๋กœ ์ฐจ๊ทผ์ฐจ๊ทผ ์ตํžˆ๋ฉด MySQL ํ™œ์šฉ ๋Šฅ๋ ฅ์ด ํ•œ์ธต ์—…๊ทธ๋ ˆ์ด๋“œ ๋  ๊ฑฐ์˜ˆ์š”!
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์˜์ƒ๊ณผ ํ•จ๊ป˜ ์ง์ ‘ ์ณ๋ณด๋ฉด์„œ ์ตํ˜€๋ณด์„ธ์š”!
#MySQL #์œˆ๋„์šฐํ•จ์ˆ˜ #๋ฐ์ดํ„ฐ๋ถ„์„ #SQL์‹ค์Šต