πŸ“Œ μœˆλ„μš° ν•¨μˆ˜(WINDOW FUNCTION)λž€?

  • μœˆλ„μš° ν•¨μˆ˜λŠ” SQLμ—μ„œ λ°μ΄ν„°λ₯Ό λΆ„μ„ν•˜κ³  μ§‘계할 λ•Œ μ‚¬μš©λ˜λŠ” νŠΉλ³„ν•œ ν•¨μˆ˜μž…λ‹ˆλ‹€.
  • 일반적인 집계 ν•¨μˆ˜(예: SUM, COUNT λ“±)λŠ” κ²°κ³Όλ₯Ό κ·Έλ£Ήν™”ν•˜μ—¬ 단일 값을 λ°˜ν™˜ν•˜λŠ” 반면, μœˆλ„μš° ν•¨μˆ˜λŠ” κ·Έλ£Ήν™”λœ λ°μ΄ν„°μ˜ 각 행에 λŒ€ν•΄ 계산을 μˆ˜ν–‰ν•˜λ©°, κ²°κ³Όλ₯Ό μƒˆλ‘œμš΄ μ—΄λ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • μœˆλ„μš° ν•¨μˆ˜λŠ” GROUP BY μ ˆμ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³ λ„ 데이터 집계λ₯Ό μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 즉, λ°μ΄ν„°μ˜ λͺ¨λ“  행에 λŒ€ν•΄ 연산을 μˆ˜ν–‰ν•˜λ©΄μ„œλ„ 각 ν–‰μ˜ 상세 정보λ₯Ό μœ μ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μœˆλ„μš° ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ λ‹¨μˆœν•œ μ§‘κ³„λΏλ§Œ μ•„λ‹ˆλΌ, μˆœμœ„, 이동 평균, λ°±λΆ„μœ¨ λ“± λ‹€μ–‘ν•œ 뢄석을 μˆ˜ν–‰ν•  수 있으며, λ³΅μž‘ν•œ μ„œλΈŒμΏΌλ¦¬λ‚˜ μžμ—° 쑰인을 μ‚¬μš©ν•˜μ§€ μ•Šκ³ λ„ λ™μΌν•œ κ²°κ³Όλ₯Ό 얻을 수 μžˆμ–΄ 쿼리 μ„±λŠ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

 

πŸ“Œ κΈ°λ³Έ 문법

SELECT
WINDOW_FUNCTION(ARGUMENTS) -- μœˆλ„μš° ν•¨μˆ˜ 호좜 (ROW_NUMBER(), RANK(), SUM() λ“±)
OVER ( -- OVER 절 μ‹œμž‘βœ¨ (μœˆλ„μš° ν•¨μˆ˜ λ™μž‘ λ²”μœ„ μ •μ˜)
[PARTITION BY 컬럼] -- 그룹을 λ‚˜λˆŒ 컬럼 μ§€μ •βœ¨
[ORDER BY 컬럼] -- κ·Έλ£Ή λ‚΄ μ •λ ¬ κΈ°μ€€ μ„€μ •
[WINDOWING 절] -- μœˆλ„μš° λ²”μœ„ μ •μ˜βœ¨
) -- OVER 절 μ’…λ£Œ
FROM
ν…Œμ΄λΈ”λͺ…; -- μ‘°νšŒν•  ν…Œμ΄λΈ” μ§€μ •

 

πŸ“Œ WINDOWING 절

κ°œμš”

뢄석할 ν–‰μ˜ λ²”μœ„λ₯Ό μ„€μ •ν•˜λ©°, ROWS와 RANGE 두 κ°€μ§€ ν‚€μ›Œλ“œλ₯Ό 톡해 μ •μ˜λ©λ‹ˆλ‹€. λ‹€μŒμ€ κΈ°λ³Έ κ΅¬λ¬Έμž…λ‹ˆλ‹€.

ROWS | RANGE BETWEEN <μ‹œμž‘μ > AND <끝점>
-- ROWS: μ‹€μ œ ν–‰ 수 κΈ°μ€€μœΌλ‘œ λ²”μœ„ μ„€μ •βœ¨
-- RANGE: κ°’μ˜ λ²”μœ„λ₯Ό κΈ°μ€€μœΌλ‘œ λ²”μœ„ μ„€μ •
  • BETWEEN ~ AND ꡬ문을 μ‚¬μš©ν•˜μ—¬ μœˆλ„μš° ν”„λ ˆμž„μ˜ μ‹œμž‘κ³Ό 끝을 μ •μ˜ν•©λ‹ˆλ‹€.
    • μ‹œμž‘μ  : UNBOUNDED PRECEDING, CURRENT ROW, λ˜λŠ” νŠΉμ • ν–‰μ˜ μƒλŒ€μ  μœ„μΉ˜λ₯Ό κΈ°μ€€μœΌλ‘œ μ§€μ •ν•©λ‹ˆλ‹€.
    • 끝점 : UNBOUNDED FOLLOWING, CURRENT ROW, λ˜λŠ” νŠΉμ • ν–‰μ˜ μƒλŒ€μ  μœ„μΉ˜λ₯Ό κΈ°μ€€μœΌλ‘œ μ§€μ •ν•©λ‹ˆλ‹€.

μ‚¬μš© μ˜ˆμ‹œ

-- BETWEEN ~ AND μ‚¬μš©βœ¨
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -- 첫 번째 ν–‰λΆ€ν„° ν˜„μž¬ ν–‰κΉŒμ§€ μ§€μ • (ν˜„μž¬ ν–‰ 포함)
-- UNBOUNDED PRECEDING: ν˜„μž¬ ν–‰ κΈ°μ€€ λͺ¨λ“  이전 ν–‰ 포함 (ν”„λ ˆμž„ μ‹œμž‘)
-- CURRENT ROW: ν˜„μž¬ ν–‰ 포함 (ν”„λ ˆμž„ 끝)
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -- ν˜„μž¬ ν–‰λΆ€ν„° λ§ˆμ§€λ§‰ ν–‰κΉŒμ§€ μ§€μ • (ν˜„μž¬ ν–‰ 포함)
-- CURRENT ROW: ν˜„μž¬ ν–‰ 포함 (ν”„λ ˆμž„ μ‹œμž‘)
-- UNBOUNDED FOLLOWING: ν˜„μž¬ ν–‰ κΈ°μ€€ λͺ¨λ“  이후 ν–‰ 포함 (ν”„λ ˆμž„ 끝)
ROWS BETWEEN VALUE_EXPR PRECEDING AND CURRENT ROW -- ν˜„μž¬ ν–‰μ—μ„œ VALUE_EXPR 만큼 이전 ν–‰κΉŒμ§€ μ§€μ • (ν˜„μž¬ ν–‰ 포함)
-- VALUE_EXPR PRECEDING: ν˜„μž¬ ν–‰μ—μ„œ VALUE_EXPR 만큼 이전 ν–‰ 포함 (ν”„λ ˆμž„ μ‹œμž‘)
-- CURRENT ROW: ν˜„μž¬ ν–‰ 포함 (ν”„λ ˆμž„ 끝)
ROWS BETWEEN CURRENT ROW AND VALUE_EXPR FOLLOWING -- ν˜„μž¬ ν–‰μ—μ„œ VALUE_EXPR 만큼 이후 ν–‰κΉŒμ§€ μ§€μ • (ν˜„μž¬ ν–‰ 포함)
-- CURRENT ROW: ν˜„μž¬ ν–‰ 포함 (ν”„λ ˆμž„ μ‹œμž‘)
-- VALUE_EXPR FOLLOWING: ν˜„μž¬ ν–‰μ—μ„œ VALUE_EXPR 만큼 이후 ν–‰ 포함 (ν”„λ ˆμž„ 끝)
-- BETWEEN ~ AND λ―Έμ‚¬μš©βœ¨
ROWS UNBOUNDED PRECEDING -- 첫 ν–‰λΆ€ν„° ν˜„μž¬ ν–‰κΉŒμ§€
ROWS CURRENT ROW -- ν˜„μž¬ ν–‰λ§Œ 포함
ROWS VALUE_EXPR PRECEDING -- ν˜„μž¬ ν–‰μ—μ„œ VALUE_EXPR 만큼 μ΄μ „μ˜ ν–‰κΉŒμ§€

 

πŸ“Œ ν•¨μˆ˜ μ’…λ₯˜λ³„ 정리

1️⃣ μˆœμœ„ κ΄€λ ¨

βœ”οΈκ°’ : 100, 200, 200, 300 일 λ•Œ,

  • ROW_NUMBER : 1, 2, 3, 4 (λͺ¨λ“  행에 λŒ€ν•΄ κ³ μœ ν•œ μˆœμœ„λ₯Ό λΆ€μ—¬ν•©λ‹ˆλ‹€.)
  • RANK : 1, 2, 2, 4 (μ€‘λ³΅λœ 값에 λŒ€ν•΄ 같은 μˆœμœ„λ₯Ό λΆ€μ—¬ν•˜κ³ , λ‹€μŒ μˆœμœ„λŠ” κ±΄λ„ˆλœλ‹ˆλ‹€.)
  • DENSE_RANK : 1, 2, 2, 3 (μ€‘λ³΅λœ 값에 λŒ€ν•΄ 같은 μˆœμœ„λ₯Ό λΆ€μ—¬ν•˜μ§€λ§Œ, λ‹€μŒ μˆœμœ„λŠ” κ±΄λ„ˆλ›°μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.✨)

2️⃣ 집계 κ΄€λ ¨

βœ”οΈκ°’ : 100, 200, 300 일 λ•Œ,

  • SUM : 600 (μ§€μ •ν•œ μ—΄μ˜ 합계λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.)
  • MAX : 300 (μ§€μ •ν•œ μ—΄μ˜ μ΅œλŒ€κ°’μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.)
  • MIN : 100 (μ§€μ •ν•œ μ—΄μ˜ μ΅œμ†Œκ°’μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.)
  • AVG : 200 (μ§€μ •ν•œ μ—΄μ˜ 평균값을 κ³„μ‚°ν•©λ‹ˆλ‹€.)
  • COUNT : 3 (ν–‰μ˜ 개수λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.)

3️⃣ ν–‰ μˆœμ„œ κ΄€λ ¨

βœ”οΈκ°’ : 100, 200, 300 일 λ•Œ,

  • FIRST_VALUE : 100 (μ§€μ •ν•œ μ—΄μ˜ 첫 번째 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.)
  • LAST_VALUE : 300 (μ§€μ •ν•œ μ—΄μ˜ λ§ˆμ§€λ§‰ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.)
  • LAG : NULL, 100, 200 (μ§€μ •ν•œ ν–‰μ˜ 이전 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.✨)
  • LEAD : 200, 300, NULL (μ§€μ •ν•œ ν–‰μ˜ λ‹€μŒ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.✨)

4️⃣ λΉ„μœ¨ κ΄€λ ¨

βœ”οΈκ°’ : 100, 200, 300 일 λ•Œ,

  • PERCENT_RANK : 0.00(0/2), 0.50, 1.00
    • λΉ„μœ¨ μˆœμœ„λ₯Ό κ³„μ‚°ν•˜μ—¬ κ° κ°’μ˜ μƒλŒ€μ  μœ„μΉ˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.✨
    • 계산 방식 : (ν˜„μž¬ μˆœμœ„ - 1) / (전체 ν–‰ 수 - 1)둜 κ³„μ‚°λ˜λ©°, 이둜 인해 κ°€μž₯ μž‘μ€ 값은 0.00, κ°€μž₯ 큰 값은 1.00을 κ°–μŠ΅λ‹ˆλ‹€.
  • CUME_DIST : 0.33(1/3), 0.67, 1.00
    • λˆ„μ  뢄포λ₯Ό κ³„μ‚°ν•˜μ—¬ 각 값보닀 μž‘κ±°λ‚˜ 같은 κ°’μ˜ λΉ„μœ¨μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.✨
    • 계산 방식 : (ν˜„μž¬ 값보닀 μž‘κ±°λ‚˜ 같은 κ°’μ˜ 개수) / (전체 ν–‰ 수)둜 κ³„μ‚°λ˜λ©°, 이둜 인해 κ°€μž₯ 큰 값은 항상 1.00을 κ°–μŠ΅λ‹ˆλ‹€.
  • RATIO_TO_REPORT : 0.17(100/600), 0.33, 0.50
    • κ°’μ˜ λΉ„μœ¨μ„ 전체 합계에 λŒ€ν•œ λΉ„μœ¨λ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€.✨
    • 계산 방식 : (νŠΉμ • κ°’) / (전체 합계)둜 κ³„μ‚°λ˜λ©°, 이λ₯Ό 톡해 νŠΉμ • 값이 μ „μ²΄μ—μ„œ μ°¨μ§€ν•˜λŠ” λΉ„μœ¨μ„ μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

     β€» Oracleμ—μ„œλ§Œ μ§€μ›λ©λ‹ˆλ‹€.

  • NTILE : (n=3일 λ•Œ)1, 2, 3
    • 행을 n개의 그룹으둜 λ‚˜λˆ„μ–΄ κ·Έλ£Ή 번호λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
    • 계산 방식 : 전체 ν–‰ 수λ₯Ό n으둜 λ‚˜λˆ„μ–΄ 각 그룹의 λ²”μœ„λ₯Ό μ •ν•˜λ©°, 각 행은 ν•΄λ‹Ή κ·Έλ£Ή 번호λ₯Ό λ°˜ν™˜λ°›μŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, n=3이면 전체 데이터가 3개의 그룹으둜 λ‚˜λ‰˜μ–΄ 각각 1, 2, 3의 κ·Έλ£Ή λ²ˆν˜Έκ°€ λΆ€μ—¬λ©λ‹ˆλ‹€.
yewon31