Windw ํจ์ : Range/Rows between
์๋์ฐ ํจ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ๋ ํ๊ฐ์ ๋ฒ์๋ฅผ ์ง์ ํ ์ ์๋ ํจ์์ด๋ค.
์๋ฅผ ๋ค์ด, ํ ๊ฐ์ sum์ ๊ตฌํ ๋, [5๊ฐ ์ด์ ํ~ํ์ฌํ] ์ ํฉ์ ๊ตฌํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ ์ ์๋ค.
๋ฌผ๋ก , ๊ทธ ๋ฒ์๋ ์์ ๋กญ๊ฒ ์ง์ ํ ์ ์๋ค.
Range/Rows between ๋ฌธ๋ฒ
- ํจ์ over ( ~ range/rows between [๋ฒ์ 1] and [๋ฒ์ 2] )
[๋จ์ ์ง์ ]
ROWS BETWEEN : ๋ฌผ๋ฆฌ์ ์ธ ๋จ์๋ก ํ ์งํฉ์ ์ง์ , order by์ ๊ฐ์ ๊ฐ์ด ์์ด๋ ๋ณ๊ฐ์ ํ์ผ๋ก ์ทจ๊ธ
RANGE BETWEEN : ๋
ผ๋ฆฌ์ ์ธ ๋จ์๋ก ์ํด ํ ์งํฉ์ ์ง์ , order by์ ๊ฐ์ ๊ฐ์ด ์์ผ๋ฉด ํ๋์ ํ์ผ๋ก ์ทจ๊ธ
[๋ฒ์ ์ง์ ]
UNBOUNDED PRECEDING : ์๋์ฐ ์์ ์์น๊ฐ ์ฒซ ๋ฒ์งธ ๋ก์ฐ์์ ์๋ฏธ
UNBOUNDED FOLLOWING : ์๋์ฐ ๋ง์ง๋ง ์์น๊ฐ ๋ง์ง๋ง ๋ก์ฐ์์ ์๋ฏธ
[ROW์] PRECEDING : ์๋์ฐ ์์ ์์น๊ฐ ROW์๋งํผ ์ด์ ์ด ์์ ๋ก์ฐ์์ ์๋ฏธ (ex. 6 preceding)
[ROW์] FOLLOWING : ์๋์ฐ ๋ง์ง๋ง ์์น๊ฐ ROW์๋งํผ ๋ค์์ด ๋ง์ง๋ง ๋ก์ฐ์์ ์๋ฏธ (ex. 6 following)
CURRENT ROW : ํ์ฌ ๋ก์ฐ๊น์ง๋ฅผ ์๋ฏธ
INTERVAL N [์๊ฐ๋จ์] PRECEDING/FOLLOWING
: range์์๋ง ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ์๊ฐ ๋จ์๋ก ๋ฒ์๋ฅผ ์ง์ ํ๋ค. (์๋ ์์ ์์ ํ์ฉ ๋ฐฉ๋ฒ์ ๋ ์์ธํ ์์๋ณด๊ฒ ๋ค)
โ ๏ธ ์ฌ๊ธฐ์ ํญ์ ํท๊ฐ๋ฆฌ๋ ๊ฒ
- 6 preceding (O) 6 row preceding (X) : ์ซ์๋ง !
- interval 6 day preceding (O) interval 6 days preceding (X) : ๋จ์์ -s(๋ณต์ํ) ์๋ถ์ !
๋ฌธ์
https://leetcode.com/problems/restaurant-growth/
์ฟผ๋ฆฌ ๋ต์
๋์ ๋งค์ฐ ์ง๊ด์ ์ธ ๋ต์
with result as (
select
visited_on,
amount,
lag(amount, 1) over (order by visited_on) as a,
lag(amount, 2) over (order by visited_on) as b,
lag(amount, 3) over (order by visited_on) as c,
lag(amount, 4) over (order by visited_on) as d,
lag(amount, 5) over (order by visited_on) as e,
lag(amount, 6) over (order by visited_on) as f
from (select visited_on, sum(amount) as amount from customer group by visited_on) as t
)
select visited_on,
(amount + a + b + c + d + e + f) as amount,
round((amount + a + b + c + d + e + f) / 7, 2) as average_amount
from result
where visited_on between '2019-01-07' and '2019-01-10'
-- 12๋ถ
ํ ๋ธ๋ก๊ทธ ํ์ด
with result_table as
(SELECT VISITED_ON
, SUM(AMOUNT) OVER(ORDER BY VISITED_ON RANGE BETWEEN INTERVAL 6 DAY PRECEDING AND CURRENT ROW) AS 'AMOUNT'
, ROUND(SUM(AMOUNT) OVER(ORDER BY VISITED_ON RANGE BETWEEN INTERVAL 6 DAY PRECEDING AND CURRENT ROW) / 7, 2) AS 'AVERAGE_AMOUNT'
FROM (SELECT VISITED_ON
, SUM(AMOUNT) AMOUNT
FROM CUSTOMER
GROUP BY VISITED_ON) as t)
select *
from result_table
WHERE VISITED_ON >= (SELECT MIN(VISITED_ON) FROM CUSTOMER) + 6 -- ์ง์ ๋ ์ง ๋ฒ์๋ฅผ ์ง์ ํ๋ ๊ฒ ์๋ ์ต์ ๋ ์ง+6์ผ๋ก ์ง์
-- ํ ํ
์ด๋ธ ์์ where์ ๋ก visited_on์ ์กฐ๊ฑด์ ๊ฑธ์ด๋ฒ๋ฆฌ๋ฉด ์ด์ ๋ ์ง์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ์ง ์์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค
ORDER BY VISITED_ON ASC
๋ฌธ์ ํ์ด
interval [๋ ์ง ์] day๋ฅผ ์ฌ์ฉํด์ 6์ผ ์ด์ ~ ํ์ฌ๊น์ง์ ๋ ์ง ๊ฐ๊ฒฉ์ ๋ฒ์๋ก ์ง์ ํ๋ค.
sum / avg ๋ฅผ ์ฌ์ฉํด์ 6์ผ ์ด์ ~ ํ์ฌ๊น์ง์ ์ด๋ํฉ / ์ด๋ํ๊ท ์ ๊ตฌํ ์ ์๋ค!
select visited_on,
amount,
sum(amount) over (order by visited_on range between interval 6 day preceding and current row) as 'amount'
from (select visited_on, sum(amount) as amount from customer group by visited_on) as t

2019-01-01 ~ 2019-01-01
2019-01-01 ~ 2019-01-02
2019-01-01 ~ 2019-01-03
2019-01-01 ~ 2019-01-04
2019-01-01 ~ 2019-01-05
2019-01-01 ~ 2019-01-06
2019-01-01 ~ 2019-01-07 -- ์ฌ๊ธฐ๋ถํฐ 7๊ฐํ ํฉ ๊ตฌํด์ง
2019-01-02 ~ 2019-01-08
2019-01-03 ~ 2019-01-09
2019-01-04~ 2019-01-10
์ด๋ ๊ฒ ๋ ์ง ๋ฒ์๋ก ํฉ์ด ๊ตฌํด์ง ๊ฑธ ๋ณผ ์ ์๋ค.
๋๋ ์
์ ๋ง ์๋ก์ด ๋ฌธ๋ฒ์ ๋๋ ์์ด ๋์ค๋๊ตฌ๋ ~~
์ด์ฌํ ๊ณต๋ถํด์ผ๊ฒ ๋ค !
'Tools > - SQL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [SQL] leetcode | 1164. Product Price at a Given Date ์์ ํ์ด (0) | 2025.01.24 |
|---|---|
| [SQL] leetcode | 3421. Find Students Who Improved ์์ ํ์ด (0) | 2025.01.24 |
| [SQL] leetcode | 1174. Immediate Food Delivery II ์์ ํ์ด (0) | 2025.01.24 |
| [SQL] leetcode | 585. Investments in 2016 ์์ ํ์ด (0) | 2025.01.23 |
| [SQL] leetcode | 180. Consecutive Numbers ์์ ํ์ด (0) | 2025.01.23 |