πŸ˜—
SQL Guide
  • πŸ˜€SQL μ „λ¬Έκ°€ κ°€μ΄λ“œμ˜ κ°€μ΄λ“œ
  • 😦과λͺ©1 데이터λͺ¨λΈμ˜ 이해
    • ⭐제1μž₯ 데이터 λͺ¨λΈλ§μ˜ 이해
      • 🌠1-1-1. 데이터 λͺ¨λΈμ˜ 이해
      • 🌠1-1-2. μ—”ν„°ν‹°(Entity)
      • 🌠1-1-3. 속성(Attribute)
      • 🌠1-1-4. 관계(Relationship)
      • 🌠1-1-5. μ‹λ³„μž
    • ⭐제2μž₯ 데이터 λͺ¨λΈκ³Ό SQL
      • 🌠1-2-1. μ •κ·œν™”
      • 🌠1-2-2. 관계와 쑰인의 이해
      • 🌠1-2-3. λͺ¨λΈμ΄ ν‘œν˜„ν•˜λŠ” νŠΈλžœμž­μ…˜μ˜ 이해
      • 🌠1-2-4. Null μ†μ„±μ˜ 이해
      • 🌠1-2-5. λ³Έμ§ˆμ‹λ³„μž vs. μΈμ‘°μ‹λ³„μž
  • 😧과λͺ©2. SQL κΈ°λ³Έκ³Ό ν™œμš©
    • ⭐제1μž₯ SQL κΈ°λ³Έ
      • 🌠2-1-1. κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€ κ°œμš”
      • 🌠2-1-2. SELECTλ¬Έ
      • 🌠2-1-3. ν•¨μˆ˜(FUNCTION)
      • 🌠2-1-4. WHERE 절
      • 🌠2-1-5. GROUP BY, HAVING 절
      • 🌠2-1-6. ORDER BY 절
      • 🌠2-1-7. 쑰인
      • 🌠2-1-8. ν‘œμ€€ 쑰인
    • ⭐제2μž₯ SQL ν™œμš©
      • 🌠2-2-1. μ„œλΈŒ 쿼리
      • 🌠2-2-2. μ§‘ν•© μ—°μ‚°μž
      • 🌠2-2-3. κ·Έλ£Ή ν•¨μˆ˜
      • 🌠2-2-4. μœˆλ„μš° ν•¨μˆ˜
      • 🌠2-2-5. Top N 쿼리
      • 🌠2-2-6. κ³„μΈ΅ν˜• μ§ˆμ˜μ™€ μ…€ν”„ 쑰인
      • 🌠2-2-7. PIVOT 절과 UNPIVOT 절
      • 🌠2-2-8. μ •κ·œ ν‘œν˜„μ‹
    • ⭐제3μž₯ 관리 ꡬ문
      • 🌠2-3-1. DML
      • 🌠2-3-2. TCL
      • 🌠2-3-3. DDL
      • 🌠2-3-4. DCL
  • 😨과λͺ©3. SQL κ³ κΈ‰ ν™œμš© 및 νŠœλ‹
    • ⭐제1μž₯ SQL μˆ˜ν–‰ ꡬ쑰
      • 🌠3-1-1. λ°μ΄ν„°λ² μ΄μŠ€ μ•„ν‚€ν…μ²˜
      • 🌠3-1-2. SQL 처리 κ³Όμ •
      • 🌠3-1-3. λ°μ΄ν„°λ² μ΄μŠ€ I/O λ©”μ»€λ‹ˆμ¦˜
    • ⭐제2μž₯ SQL 뢄석 도ꡬ
      • 🌠3-2-1. μ˜ˆμƒ μ‹€ν–‰κ³„νš
      • 🌠3-2-2. SQL 트레이슀
      • 🌠3-2-3. 응닡 μ‹œκ°„ 뢄석
    • ⭐제3μž₯ 인덱슀 νŠœλ‹
      • 🌠3-3-1. 인덱슀 κΈ°λ³Έ 원리
      • 🌠3-3-2. ν…Œμ΄λΈ” μ•‘μ„ΈμŠ€ μ΅œμ†Œν™”
      • 🌠3-3-3. 인덱슀 μŠ€μΊ” νš¨μœ¨ν™”
      • 🌠3-3-4. 인덱슀 섀계
    • ⭐제4μž₯ 쑰인 νŠœλ‹
      • 🌠3-4-1. NL 쑰인
      • 🌠3-4-2. μ†ŒνŠΈ λ¨Έμ§€ 쑰인
      • 🌠3-4-3. ν•΄μ‹œ 쑰인
      • 🌠3-4-4. 슀칼라 μ„œλΈŒμΏΌλ¦¬
      • 🌠3-4-5. κ³ κΈ‰ 쑰인 기법
    • ⭐제5μž₯ SQL μ˜΅ν‹°λ§ˆμ΄μ €
      • 🌠3-5-1. SQL μ˜΅ν‹°λ§ˆμ΄μ§• 원리
      • 🌠3-5-2. SQL 곡유 및 μž¬μ‚¬μš©
      • 🌠3-5-3. 쿼리 λ³€ν™˜
    • ⭐제6μž₯ κ³ κΈ‰ SQL νŠœλ‹
      • 🌠3-6-1. μ†ŒνŠΈ νŠœλ‹
      • 🌠3-6-2. DML νŠœλ‹
      • 🌠3-6-3. λ°μ΄ν„°λ² μ΄μŠ€ Call μ΅œμ†Œν™”
      • 🌠3-6-4. νŒŒν‹°μ…”λ‹
      • 🌠3-6-5. λŒ€μš©λŸ‰ 배치 ν”„λ‘œκ·Έλž¨ νŠœλ‹
      • 🌠3-6-6. κ³ κΈ‰ SQL ν™œμš©
    • ⭐제7μž₯ Lockκ³Ό νŠΈλžœμž­μ…˜ λ™μ‹œμ„± μ œμ–΄
      • 🌠3-7-1. Lock
      • 🌠3-7-2. νŠΈλžœμž­μ…˜
      • 🌠3-7-3. λ™μ‹œμ„± μ œμ–΄
Powered by GitBook
On this page
  • κ³Όλͺ©2. SQL κΈ°λ³Έκ³Ό ν™œμš©
  • 제1μž₯ SQL κΈ°λ³Έ
  • 제5절 GROUP BY, HAVING 절
  • 1. 집계 ν•¨μˆ˜(Aggregate Function)
  • 2. GROUP BY 절
  • 3. HAVING 절
  • 4. CASE ν‘œν˜„μ„ ν™œμš©ν•œ 월별 데이터 집계
  • 5. 집계 ν•¨μˆ˜μ™€ NULL 처리

Was this helpful?

  1. κ³Όλͺ©2. SQL κΈ°λ³Έκ³Ό ν™œμš©
  2. 제1μž₯ SQL κΈ°λ³Έ

2-1-5. GROUP BY, HAVING 절

κ³Όλͺ©2. SQL κΈ°λ³Έκ³Ό ν™œμš©

제1μž₯ SQL κΈ°λ³Έ

제5절 GROUP BY, HAVING 절

1. 집계 ν•¨μˆ˜(Aggregate Function)

μ—¬λŸ¬ ν–‰λ“€μ˜ 그룹이 λͺ¨μ—¬μ„œ κ·Έλ£Ήλ‹Ή 단 ν•˜λ‚˜μ˜ κ²°κ³Όλ₯Ό λŒλ €μ£ΌλŠ” 닀쀑행 ν•¨μˆ˜ 쀑 집계 ν•¨μˆ˜(Aggregate Function)의 νŠΉμ„±μ€ λ‹€μŒκ³Ό κ°™λ‹€.

  • μ—¬λŸ¬ ν–‰λ“€μ˜ 그룹이 λͺ¨μ—¬μ„œ κ·Έλ£Ήλ‹Ή 단 ν•˜λ‚˜μ˜ κ²°κ³Όλ₯Ό λŒλ €μ£ΌλŠ” ν•¨μˆ˜μ΄λ‹€.

  • GROUP BY μ ˆμ€ 행듀을 μ†Œκ·Έλ£Ήν™” ν•œλ‹€.

  • SELECT 절, HAVING 절, ORDER BY μ ˆμ— μ‚¬μš©ν•  수 μžˆλ‹€.

ANSI/ISOμ—μ„œ 데이터 뢄석 κΈ°λŠ₯으둜 λΆ„λ₯˜ν•œ ν•¨μˆ˜ 쀑 기본적인 집계 ν•¨μˆ˜λŠ” λ³Έ μ ˆμ—μ„œ μ„€λͺ…ν•˜κ³ , ROLLUP, CUBE, GROUPING SETS 같은 GROUP ν•¨μˆ˜λŠ” 2μž₯ 5μ ˆμ—μ„œ, λ‹€μ–‘ν•œ 뢄석 κΈ°λŠ₯을 κ°€μ§„ WINDOW ν•¨μˆ˜λŠ” 2μž₯ 4μ ˆμ—μ„œ μ„€λͺ…ν•œλ‹€.

집계 ν•¨μˆ˜λͺ… ( [DISTINCT | ALL] μΉΌλŸΌμ΄λ‚˜ ν‘œν˜„μ‹ )

μ§‘κ³„ν•¨μˆ˜λͺ…에 μ‚¬μš©λ˜λŠ” 2κ°€μ§€ μ˜΅μ…˜μ— λŒ€ν•œ μ„€λͺ…은 λ‹€μŒκ³Ό κ°™λ‹€.

  • ALL : Default μ˜΅μ…˜μ΄λ―€λ‘œ μƒλž΅ κ°€λŠ₯함

  • DISTINCT : 같은 값을 ν•˜λ‚˜μ˜ λ°μ΄ν„°λ‘œ κ°„μ£Όν•  λ•Œ μ‚¬μš©ν•˜λŠ” μ˜΅μ…˜μž„

자주 μ‚¬μš©λ˜λŠ” μ£Όμš” 집계 ν•¨μˆ˜λ“€μ€ λ‹€μŒκ³Ό κ°™λ‹€. 집계 ν•¨μˆ˜λŠ” 그룹에 λŒ€ν•œ 정보λ₯Ό μ œκ³΅ν•˜λ―€λ‘œ 주둜 숫자 μœ ν˜•μ— μ‚¬μš©λ˜μ§€λ§Œ, MAX, MIN, COUNT ν•¨μˆ˜λŠ” 문자, λ‚ μ§œ μœ ν˜•μ—λ„ 적용이 κ°€λŠ₯ν•œ ν•¨μˆ˜μ΄λ‹€.

[예제] 일반적으둜 집계 ν•¨μˆ˜λŠ” GROUP BY 절과 같이 μ‚¬μš©λ˜μ§€λ§Œ μ•„λž˜μ™€ 같이 ν…Œμ΄λΈ” 전체가 ν•˜λ‚˜μ˜ 그룹이 λ˜λŠ” κ²½μš°μ—λŠ” GROUP BY 절 없이 λ‹¨λ…μœΌλ‘œλ„ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.

[예제]

SELECT COUNT(*)              "전체 ν–‰μˆ˜"
    , COUNT(HEIGHT)         "ν‚€ 건수"
    , MAX(HEIGHT)           μ΅œλŒ€ν‚€
    , MIN(HEIGHT)           μ΅œμ†Œν‚€
    , ROUND(AVG(HEIGHT), 2) 평균킀
 FROM PLAYER; 

[μ‹€ν–‰ κ²°κ³Ό]

전체 ν–‰μˆ˜
ν‚€ 건수
μ΅œλŒ€ν‚€
μ΅œμ†Œν‚€
평균킀

480

447

196

165

179.31

1 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ‹€ν–‰ κ²°κ³Όλ₯Ό 보면 COUNT(HEIGHT)λŠ” NULL값이 μ•„λ‹Œ ν‚€(HEIGHT) 칼럼의 건수만 좜λ ₯ν•˜λ―€λ‘œ COUNT(*)의 480보닀 μž‘μ€ 것을 λ³Ό 수 μžˆλ‹€. κ·Έ μ΄μœ λŠ” COUNT(*) ν•¨μˆ˜μ— μ‚¬μš©λœ μ™€μΌλ“œμΉ΄λ“œ(*)λŠ” 전체 μΉΌλŸΌμ„ λœ»ν•˜λŠ”λ° 전체 칼럼이 NULL인 행은 μ‘΄μž¬ν•  수 μ—†κΈ° λ•Œλ¬Έμ— κ²°κ΅­ COUNT(*)λŠ” 전체 ν–‰μ˜ 개수λ₯Ό 좜λ ₯ν•œ 것이고, COUNT(HEIGHT)λŠ” HEIGHT 칼럼 값이 NULL인 33건은 μ œμ™Έλœ 건수의 합이닀.

2. GROUP BY 절

WHERE μ ˆμ„ 톡해 쑰건에 λ§žλŠ” 데이터λ₯Ό μ‘°νšŒν–ˆμ§€λ§Œ ν…Œμ΄λΈ”μ— 1차적으둜 μ‘΄μž¬ν•˜λŠ” 데이터 μ΄μ™Έμ˜ 정보, 예λ₯Ό λ“€λ©΄ 각 νŒ€λ³„λ‘œ μ„ μˆ˜κ°€ λͺ‡ λͺ…인지, μ„ μˆ˜λ“€μ˜ 평균 μ‹ μž₯κ³Ό λͺΈλ¬΄κ²Œκ°€ μ–Όλ§ˆλ‚˜ λ˜λŠ”μ§€, λ˜λŠ” 각 νŒ€μ—μ„œ κ°€μž₯ 큰 ν‚€μ˜ μ„ μˆ˜κ°€ λˆ„κ΅¬μΈμ§€ λ“±μ˜ 2μ°¨ 가곡 정보도 ν•„μš”ν•˜λ‹€. GROUP BY μ ˆμ€ SQL λ¬Έμ—μ„œ FROM 절과 WHERE 절 뒀에 였며, 데이터듀을 μž‘μ€ 그룹으둜 λΆ„λ₯˜ν•˜μ—¬ μ†Œκ·Έλ£Ήμ— λŒ€ν•œ ν•­λͺ©λ³„λ‘œ 톡계 정보λ₯Ό 얻을 λ•Œ μΆ”κ°€λ‘œ μ‚¬μš©λœλ‹€.

SELECT [DISTINCT] 칼럼 [ALIASλͺ…]
 FROM ν…Œμ΄λΈ”λͺ…
[WHERE 쑰건식]
[GROUP BY 칼럼(Column)μ΄λ‚˜ ν‘œν˜„μ‹]
[HAVING 그룹쑰건식];

GROUP BY 절과 HAVING μ ˆμ€ λ‹€μŒκ³Ό 같은 νŠΉμ„±μ„ κ°€μ§„λ‹€.

  • GROUP BY μ ˆμ„ 톡해 μ†Œκ·Έλ£Ήλ³„ 기쀀을 μ •ν•œ ν›„, SELECT μ ˆμ— 집계 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€.

  • 집계 ν•¨μˆ˜μ˜ 톡계 μ •λ³΄λŠ” NULL 값을 κ°€μ§„ 행을 μ œμ™Έν•˜κ³  μˆ˜ν–‰ν•œλ‹€.

  • GROUP BY μ ˆμ—μ„œλŠ” SELECT μ ˆκ³ΌλŠ” 달리 ALIAS λͺ…을 μ‚¬μš©ν•  수 μ—†λ‹€.

  • 집계 ν•¨μˆ˜λŠ” WHERE μ ˆμ—λŠ” 올 수 μ—†λ‹€. (집계 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” GROUP BY μ ˆλ³΄λ‹€ WHERE 절이 λ¨Όμ € μˆ˜ν–‰λœλ‹€)

  • WHERE μ ˆμ€ 전체 데이터λ₯Ό GROUP으둜 λ‚˜λˆ„κΈ° 전에 행듀을 미리 μ œκ±°μ‹œν‚¨λ‹€.

  • HAVING μ ˆμ€ GROUP BY 절의 κΈ°μ€€ ν•­λͺ©μ΄λ‚˜ μ†Œκ·Έλ£Ήμ˜ 집계 ν•¨μˆ˜λ₯Ό μ΄μš©ν•œ 쑰건을 ν‘œμ‹œν•  수 μžˆλ‹€.

  • GROUP BY μ ˆμ— μ˜ν•œ μ†Œκ·Έλ£Ήλ³„λ‘œ λ§Œλ“€μ–΄μ§„ 집계 데이터 쀑, HAVING μ ˆμ—μ„œ μ œν•œ 쑰건을 두어 쑰건을 λ§Œμ‘±ν•˜λŠ” λ‚΄μš©λ§Œ 좜λ ₯ν•œλ‹€.

  • HAVING μ ˆμ€ 일반적으둜 GROUP BY 절 뒀에 μœ„μΉ˜ν•œλ‹€.

일뢀 λ°μ΄ν„°λ² μ΄μŠ€μ˜ κ³Όκ±° λ²„μ „μ—μ„œ λ°μ΄ν„°λ² μ΄μŠ€κ°€ GROUP BY μ ˆμ— λͺ…μ‹œλœ 칼럼의 μˆœμ„œλŒ€λ‘œ μ˜€λ¦„μ°¨μˆœ 정렬을 μžλ™μœΌλ‘œ μ‹€μ‹œ(비곡식적인 μ§€μ›μ΄μ—ˆμŒ)ν•˜λŠ” κ²½μš°κ°€ μžˆμ—ˆμœΌλ‚˜, μ›μΉ™μ μœΌλ‘œ κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€ ν™˜κ²½μ—μ„œλŠ” λ’€μ—μ„œ μ–ΈκΈ‰ν•  ORDER BY μ ˆμ„ λͺ…μ‹œν•΄μ•Ό 데이터 정렬이 μˆ˜ν–‰λœλ‹€. ANSI/ISO κΈ°μ€€μ—μ„œλ„ 데이터 정렬에 λŒ€ν•œ λ‚΄μš©μ€ ORDER BY μ ˆμ—μ„œλ§Œ μ–ΈκΈ‰λ˜μ–΄μžˆμ§€, GROUP BY μ ˆμ—λŠ” μ–ΈκΈ‰λ˜μ–΄ μžˆμ§€ μ•Šλ‹€.

[예제] K-리그 μ„ μˆ˜λ“€μ˜ ν¬μ§€μ…˜λ³„ ν‰κ· ν‚€λŠ” μ–΄λ–»κ²Œ λ˜λŠ”κ°€λž€ μš”κ΅¬ 사항을 μ ‘μˆ˜ν•˜μ˜€λ‹€. GROUP BY μ ˆμ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³  집계 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν–ˆμ„ λ•Œ μ–΄λ–€ κ²°κ³Όλ₯Ό λ³΄μ΄λŠ”μ§€ ν¬μ§€μ…˜λ³„ 평균킀λ₯Ό ꡬ해본닀.

[예제]

SELECT POSITION ν¬μ§€μ…˜, AVG(HEIGHT) 평균킀
 FROM PLAYER; 

[μ‹€ν–‰ κ²°κ³Ό]

SELECT POSITION ν¬μ§€μ…˜, AVG(HEIGHT) 평균킀
*
1ν–‰μ—μ˜€λ₯˜:
ERROR: λ‹¨μΌκ·Έλ£Ήμ˜μ§‘κ³„ν•¨μˆ˜κ°€μ•„λ‹™λ‹ˆλ‹€.

GROUP BY μ ˆμ—μ„œ κ·Έλ£Ή λ‹¨μœ„λ₯Ό ν‘œμ‹œν•΄ μ£Όμ–΄μ•Ό SELECT μ ˆμ—μ„œ κ·Έλ£Ή λ‹¨μœ„μ˜ 칼럼과 집계 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ μ˜ˆμ œμ™€ 같이 μ—λŸ¬λ₯Ό λ°œμƒν•˜κ²Œ λœλ‹€.

[예제] SELECT μ ˆμ—μ„œ μ‚¬μš©λœ ν¬μ§€μ…˜μ΄λΌλŠ” ν•œκΈ€ ALIASλ₯Ό GROUP BY 절의 κΈ°μ€€μœΌλ‘œ μ‚¬μš©ν•΄λ³Έλ‹€.

[예제]

SELECT POSITION    ν¬μ§€μ…˜
    , AVG(HEIGHT) 평균킀
 FROM PLAYER
GROUP BY POSITION ν¬μ§€μ…˜; 

[μ‹€ν–‰ κ²°κ³Ό]

GROUP BY POSITION ν¬μ§€μ…˜

  • 3행에 였λ₯˜: ERROR: SQL λͺ…λ Ήμ–΄κ°€ μ˜¬λ°”λ₯΄κ²Œ μ’…λ£Œλ˜μ§€ μ•Šμ•˜λ‹€.

μ‹€ν–‰ κ²°κ³Όλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ GROUP BY μ ˆμ— "ν¬μ§€μ…˜"이라고 ν‘œμ‹œλœ 뢀뢄에 μ—λŸ¬κ°€ λ°œμƒν–ˆλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. μΉΌλŸΌμ— λŒ€ν•œ ALIASλŠ” SELECT μ ˆμ—μ„œ μ •μ˜ν•˜κ³  ORDER BY μ ˆμ—μ„œλŠ” μž¬ν™œμš©ν•  수 μžˆμ§€λ§Œ, GROUP BY μ ˆμ—μ„œλŠ” ALIAS λͺ…을 μ‚¬μš©ν•  수 μ—†λ‹€λŠ” 것을 보여 μ£ΌλŠ” 사둀이닀.

[예제] ν¬μ§€μ…˜λ³„ μ΅œλŒ€ν‚€, μ΅œμ†Œν‚€, 평균킀λ₯Ό 좜λ ₯ν•œλ‹€. (ν¬μ§€μ…˜λ³„μ΄λž€ μ†Œκ·Έλ£Ήμ˜ 쑰건을 μ œμ‹œν•˜μ˜€κΈ° λ•Œλ¬Έμ— GROUP BY μ ˆμ„ μ‚¬μš©ν•œλ‹€.)

[예제]

SELECT POSITION              ν¬μ§€μ…˜
    , COUNT(*)              μΈμ›μˆ˜
    , COUNT(HEIGHT)         ν‚€λŒ€μƒ
    , MAX(HEIGHT)           μ΅œλŒ€ν‚€
    , MIN(HEIGHT)           μ΅œμ†Œν‚€
    , ROUND(AVG(HEIGHT), 2) 평균킀
 FROM PLAYER
GROUP BY POSITION; 

[μ‹€ν–‰ κ²°κ³Ό]

μ‹€ν–‰ κ²°κ³Όλ₯Ό 보면 ν¬μ§€μ…˜λ³„λ‘œ 평균킀 외에도 μΈμ›μˆ˜, ν‚€λŒ€μƒ μΈμ›μˆ˜, μ΅œλŒ€ν‚€, μ΅œμ†Œν‚€κ°€ μ œλŒ€λ‘œ 좜λ ₯된 것을 확인할 수 μžˆλ‹€. ORDER BY 절이 μ—†κΈ° λ•Œλ¬Έμ— ν¬μ§€μ…˜ λ³„λ‘œ 정렬은 λ˜μ§€ μ•Šμ•˜λ‹€. μΆ”κ°€λ‘œ ν¬μ§€μ…˜κ³Ό ν‚€ 정보가 μ—†λŠ” μ„ μˆ˜κ°€ 3λͺ…μ΄λΌλŠ” 정보λ₯Ό 얻을 수 있으며, ν¬μ§€μ…˜μ΄ DF인 172λͺ… 쀑 30λͺ…은 킀에 λŒ€ν•œ 정보가 μ—†λŠ” 것도 μ•Œ 수 μžˆλ‹€. GK, DF, FW, MF의 μ΅œλŒ€ν‚€, μ΅œμ†Œν‚€, 평균킀λ₯Ό ꡬ할 λ•Œ ν‚€ 값이 NULL인 κ²½μš°λŠ” 계산 λŒ€μƒμ—μ„œ μ œμ™Έλœλ‹€. 즉 ν¬μ§€μ…˜ DF의 μ΅œλŒ€ν‚€, μ΅œμ†Œν‚€, 평균킀 κ²°κ³ΌλŠ” ν‚€ 값이 NULL인 30λͺ…을 μ œμ™Έν•œ 142λͺ…을 λŒ€μƒμœΌλ‘œ μˆ˜ν–‰ν•œ 톡계 결과이닀.

3. HAVING 절

[예제] K-리그 μ„ μˆ˜λ“€μ˜ ν¬μ§€μ…˜λ³„ 평균킀λ₯Ό κ΅¬ν•˜λŠ”λ°, 평균킀가 180 μ„Όν‹°λ―Έν„° 이상인 μ •λ³΄λ§Œ ν‘œμ‹œν•˜λΌλŠ” μš”κ΅¬ 사항이 μ ‘μˆ˜λ˜μ—ˆμœΌλ―€λ‘œ WHERE 절과 GROUP BY μ ˆμ„ μ‚¬μš©ν•΄ SQL λ¬Έμž₯을 μž‘μ„±ν•œλ‹€.

[예제]

SELECT POSITION              ν¬μ§€μ…˜
    , ROUND(AVG(HEIGHT), 2) 평균킀
 FROM PLAYER
WHERE AVG(HEIGHT) >= 180
GROUP BY POSITION; 

[μ‹€ν–‰ κ²°κ³Ό]

WHERE AVG(HEIGHT) >= 180

  • 3행에 였λ₯˜: ERROR: 집계 ν•¨μˆ˜λŠ” ν—ˆκ°€λ˜μ§€ μ•ŠλŠ”λ‹€.

μ‹€ν–‰ κ²°κ³Όμ—μ„œ WHERE 절의 집계 ν•¨μˆ˜ AVG(HEIGHT) λΆ€λΆ„μ—μ„œ "집계 ν•¨μˆ˜λŠ” ν—ˆκ°€λ˜μ§€ μ•ŠλŠ”λ‹€"λŠ” μ—λŸ¬ λ©”μ‹œμ§€κ°€ 좜λ ₯λ˜μ—ˆλ‹€. 즉 WHERE μ ˆμ—λŠ” AVG()λΌλŠ” 집계 ν•¨μˆ˜λŠ” μ‚¬μš©ν•  수 μ—†λ‹€. WHERE μ ˆμ€ FROM μ ˆμ— μ •μ˜λœ μ§‘ν•©(주둜 ν…Œμ΄λΈ”)의 κ°œλ³„ 행에 WHERE 절의 쑰건절이 λ¨Όμ € 적용되고, WHERE 절의 쑰건에 λ§žλŠ” 행이 GROUP BY 절의 λŒ€μƒμ΄ λœλ‹€. 그런 λ‹€μŒ κ²°κ³Ό μ§‘ν•©μ˜ 행에 HAVING 쑰건절이 μ μš©λœλ‹€. 결과적으둜 HAVING 절의 쑰건을 λ§Œμ‘±ν•˜λŠ” λ‚΄μš©λ§Œ 좜λ ₯λœλ‹€. 즉 HAVING μ ˆμ€ WHERE 절과 λΉ„μŠ·ν•˜μ§€λ§Œ 그룹을 λ‚˜νƒ€λ‚΄λŠ” κ²°κ³Ό μ§‘ν•©μ˜ 행에 쑰건이 μ μš©λœλ‹€λŠ” μ μ—μ„œ 차이가 μžˆλ‹€.

[예제] HAVING μ‘°κ±΄μ ˆμ—λŠ” GROUP BY μ ˆμ—μ„œ μ •μ˜ν•œ μ†Œκ·Έλ£Ήμ˜ 집계 ν•¨μˆ˜λ₯Ό μ΄μš©ν•œ 쑰건을 ν‘œμ‹œν•  수 μžˆμœΌλ―€λ‘œ, HAVING μ ˆμ„ μ΄μš©ν•΄ 평균킀가 180 μ„Όν‹°λ―Έν„° 이상인 μ •λ³΄λ§Œ ν‘œμ‹œν•œλ‹€.

[예제]

SELECT POSITION ν¬μ§€μ…˜
    , ROUND(AVG(HEIGHT), 2) 평균킀
 FROM PLAYER
GROUP BY POSITION
HAVING AVG(HEIGHT) >= 180; 

[μ‹€ν–‰ κ²°κ³Ό]

ν¬μ§€μ…˜
평균킀

GK

186.26

DF

180.21

2 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

GROUP BY 절과 HAVING 절의 μˆœμ„œλ₯Ό λ°”κΎΈμ–΄μ„œ μˆ˜ν–‰ν•˜λ”λΌλ„ 문법 μ—λŸ¬κ°€ μ—†κ³  결과물도 λ™μΌν•œ κ²°κ³Όλ₯Ό 좜λ ₯ν•œλ‹€(SQL Serverμ—μ„œλŠ” λ¬Έλ²•μ˜€λ₯˜κ°€ λ°œμƒν•œλ‹€). μ‹€ν–‰ κ²°κ³Όμ—μ„œ 전체 4개 ν¬μ§€μ…˜ μ€‘μ—μ„œ 평균 ν‚€κ°€ 180cmκ°€ λ„˜λŠ” 2개의 λ°μ΄ν„°λ§Œ 좜λ ₯된 것을 확인할 수 μžˆλ‹€.

[예제] SQL λ¬Έμž₯은 GROUP BY 절과 HAVING 절의 μˆœμ„œλ₯Ό λ°”κΎΈμ–΄μ„œ μˆ˜ν–‰ν•œλ‹€.

[예제]

SELECT POSITION ν¬μ§€μ…˜
    , AVG(HEIGHT) 평균킀
 FROM PLAYER
HAVING AVG(HEIGHT) >= 180
GROUP BY POSITION; 

[μ‹€ν–‰ κ²°κ³Ό]

ν¬μ§€μ…˜
평균킀

GK

186.26

DF

180.21

2 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

GROUP BY 절과 HAVING 절의 μˆœμ„œλ₯Ό λ°”κΎΈμ–΄μ„œ μˆ˜ν–‰ν•˜λ”λΌλ„ 문법 μ—λŸ¬λ„ μ—†κ³  결과물도 λ™μΌν•œ κ²°κ³Όλ₯Ό 좜λ ₯ν•œλ‹€. κ·Έλ ‡μ§€λ§Œ, SQL λ‚΄μš©μ„ 보면, ν¬μ§€μ…˜μ΄λž€ μ†Œκ·Έλ£ΉμœΌλ‘œ κ·Έλ£Ήν•‘(GROUPING)λ˜μ–΄ 톡계 정보가 λ§Œλ“€μ–΄μ§€κ³ , 이후 적용된 κ²°κ³Ό 값에 λŒ€ν•œ HAVING 절의 μ œν•œ 쑰건에 λ§žλŠ” λ°μ΄ν„°λ§Œμ„ 좜λ ₯ν•˜λŠ” κ²ƒμ΄λ―€λ‘œ λ…Όλ¦¬μ μœΌλ‘œ GROUP BY 절과 HAVING 절의 μˆœμ„œλ₯Ό μ§€ν‚€λŠ” 것을 κΆŒκ³ ν•œλ‹€.

[예제] K-리그의 μ„ μˆ˜λ“€ 쀑 μ‚Όμ„±λΈ”λ£¨μœ™μ¦ˆ(K02)와 FCμ„œμšΈ(K09)의 μΈμ›μˆ˜λŠ” μ–Όλ§ˆμΈκ°€λž€ μš”κ΅¬ 사항이 μ ‘μˆ˜λ˜μ—ˆλ‹€. WHERE 절과 GROUP BY μ ˆμ„ μ‚¬μš©ν•œ SQLκ³Ό GROUP BY 절과 HAVING μ ˆμ„ μ‚¬μš©ν•œ SQL을 λͺ¨λ‘ μž‘μ„±ν•œλ‹€.

[예제]

SELECT TEAM_ID  νŒ€ID
    , COUNT(*) μΈμ›μˆ˜
 FROM PLAYER
WHERE TEAM_ID IN ( 'K09', 'K02' )
GROUP BY TEAM_ID; 

[예제]

SELECT TEAM_ID  νŒ€ID
    , COUNT(*) μΈμ›μˆ˜
 FROM PLAYER
GROUP BY TEAM_ID
HAVING TEAM_ID IN ( 'K09', 'K02' ); 

[μ‹€ν–‰ κ²°κ³Ό]

νŒ€ID
μΈμ›μˆ˜

K02

49

K09

49

2 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

GROUP BY μ†Œκ·Έλ£Ήμ˜ 데이터 쀑 μΌλΆ€λ§Œ ν•„μš”ν•œ 경우, GROUP BY μ—°μ‚° μ „ WHERE μ ˆμ—μ„œ 쑰건을 μ μš©ν•˜μ—¬ ν•„μš”ν•œ λ°μ΄ν„°λ§Œ μΆ”μΆœν•˜μ—¬ GROUP BY 연산을 ν•˜λŠ” 방법과, GROUP BY μ—°μ‚° ν›„ HAVING μ ˆμ—μ„œ ν•„μš”ν•œ λ°μ΄ν„°λ§Œ 필터링 ν•˜λŠ” 두 κ°€μ§€ 방법을 μ‚¬μš©ν•  수 μžˆλ‹€. 같은 μ‹€ν–‰ κ²°κ³Όλ₯Ό μ–»λŠ” 두 κ°€μ§€ 방법 쀑 HAVING μ ˆμ—μ„œ TEAM_ID 같은 GROUP BY κΈ°μ€€ μΉΌλŸΌμ— λŒ€ν•œ 쑰건을 μΆ”κ°€ν•  μˆ˜λ„ μžˆμœΌλ‚˜, κ°€λŠ₯ν•˜λ©΄ WHERE μ ˆμ—μ„œ μ‘°κ±΄μ ˆμ„ μ μš©ν•˜μ—¬ GROUP BY의 계산 λŒ€μƒμ„ μ€„μ΄λŠ” 것이 효율적인 μžμ› μ‚¬μš© μΈ‘λ©΄μ—μ„œ λ°”λžŒμ§ν•˜λ‹€.

[예제] ν¬μ§€μ…˜λ³„ ν‰κ· ν‚€λ§Œ 좜λ ₯ν•˜λŠ”λ°, μ΅œλŒ€ν‚€κ°€ 190cm 이상인 μ„ μˆ˜λ₯Ό κ°€μ§€κ³  μžˆλŠ” ν¬μ§€μ…˜μ˜ μ •λ³΄λ§Œ 좜λ ₯ν•œλ‹€.

[예제]

SELECT POSITION ν¬μ§€μ…˜
    , ROUND(AVG(HEIGHT), 2) 평균킀
 FROM PLAYER
GROUP BY POSITION
HAVING MAX(HEIGHT) >= 190; 

[μ‹€ν–‰ κ²°κ³Ό]

ν¬μ§€μ…˜
평균킀

GK

186.26

DF

180.21

FW

179.91

3 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

SQL을 보면 SELECT μ ˆμ—μ„œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” MAX 집계 ν•¨μˆ˜λ₯Ό HAVING μ ˆμ—μ„œ 쑰건절둜 μ‚¬μš©ν•œ 사둀이닀. 즉 HAVING μ ˆμ€ SELECT μ ˆμ— μ‚¬μš©λ˜μ§€ μ•Šμ€ μΉΌλŸΌμ΄λ‚˜ 집계 ν•¨μˆ˜κ°€ μ•„λ‹ˆλ”λΌλ„ GROUP BY 절의 κΈ°μ€€ ν•­λͺ©μ΄λ‚˜ μ†Œκ·Έλ£Ήμ˜ 집계 ν•¨μˆ˜λ₯Ό μ΄μš©ν•œ 쑰건을 ν‘œμ‹œν•  수 μžˆλ‹€. 이 뢀뢄은 1μž₯ 8절의 SELECT λ¬Έμž₯의 μ‹€ν–‰ μˆœμ„œμ—μ„œ μΆ”κ°€ μ„€λͺ…ν•œλ‹€. μ—¬κΈ°μ„œ μ£Όμ˜ν•  것은 WHERE 절의 쑰건 변경은 λŒ€μƒ λ°μ΄ν„°μ˜ κ°œμˆ˜κ°€ λ³€κ²½λ˜λ―€λ‘œ κ²°κ³Ό 데이터 값이 변경될 수 μžˆμ§€λ§Œ, HAVING 절의 쑰건 변경은 κ²°κ³Ό 데이터 변경은 μ—†κ³  좜λ ₯λ˜λŠ” λ ˆμ½”λ“œμ˜ 개수만 변경될 수 μžˆλ‹€. μ‹€ν–‰ κ²°κ³Όλ₯Ό 보면 λ‹€λ₯Έ κ²°κ³Ό κ°’μ˜ λ³€κ²½ 없이 MAX(HEIGHT)κ°€ 189cm둜 190cm 미만인 MF ν¬μ§€μ…˜μ˜ λ°μ΄ν„°λ§Œ HAVING 쑰건에 μ˜ν•΄ λˆ„λ½λœ 것을 확인할 수 μžˆλ‹€. (λ‹€λ₯Έ ν¬μ§€μ…˜μ€ λͺ¨λ‘ MAX(HEIGHT)κ°€ 190이상이닀). λˆ„λ½λœ λ°μ΄ν„°μ˜ 톡계 μ •λ³΄λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

ν¬μ§€μ…˜
μΈμ›μˆ˜
ν‚€λŒ€μƒ
μ΅œλŒ€ν‚€
μ΅œμ†Œν‚€
평균킀

3

0

MF

162

162

189

165

176.31

2 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

4. CASE ν‘œν˜„μ„ ν™œμš©ν•œ 월별 데이터 집계

"집계 ν•¨μˆ˜(CASE( ))~GROUP BY" κΈ°λŠ₯은, λͺ¨λΈλ§μ˜ 제1μ •κ·œν™”λ‘œ 인해 λ°˜λ³΅λ˜λŠ” 칼럼의 경우 ꡬ뢄 μΉΌλŸΌμ„ 두고 μ—¬λŸ¬ 개의 λ ˆμ½”λ“œλ‘œ λ§Œλ“€μ–΄μ§„ 집합을, μ •ν•΄μ§„ 칼럼 수만큼 ν™•μž₯ν•΄μ„œ 집계 λ³΄κ³ μ„œλ₯Ό λ§Œλ“œλŠ” μœ μš©ν•œ 기법이닀. λΆ€μ„œλ³„λ‘œ 월별 μž…μ‚¬μžμ˜ 평균 κΈ‰μ—¬λ₯Ό μ•Œκ³  μ‹Άλ‹€λŠ” 고객의 μš”κ΅¬ 사항이 μžˆλŠ”λ°, μž…μ‚¬ ν›„ 1λ…„λ§ˆλ‹€ κΈ‰μ—¬ μΈμƒμ΄λ‚˜ λ³΄λ„ˆμŠ€ μ§€κΈ‰κ³Ό 같은 일정이 μ •κΈ°μ μœΌλ‘œ μž‘νžŒλ‹€λ©΄ μ—…λ¬΄μ μœΌλ‘œ μ€‘μš”ν•œ 정보가 될 수 μžˆλ‹€.

STEP1. κ°œλ³„ 데이터 확인

[예제] λ¨Όμ € κ°œλ³„ μž…μ‚¬μ •λ³΄μ—μ„œ 월별 데이터λ₯Ό μΆ”μΆœν•˜λŠ” μž‘μ—…μ„ μ§„ν–‰ν•œλ‹€. 이 λ‹¨κ³„λŠ” 월별 정보가 μžˆλ‹€λ©΄ μƒλž΅ κ°€λŠ₯ν•˜λ‹€.

[예제] Oracle

SELECT ENAME, DEPTNO
    , EXTRACT(MONTH FROM HIREDATE) μž…μ‚¬μ›”, SAL
 FROM EMP; 

[예제] SQL Server

SELECT ENAME, DEPTNO
    , DATEPART(MONTH, HIREDATE) μž…μ‚¬μ›”, SAL
 FROM EMP; 

[예제] SQL Server

SELECT ENAME, DEPTNO
    , MONTH(HIREDATE) μž…μ‚¬μ›”, SAL
 FROM EMP; 

[μ‹€ν–‰ κ²°κ³Ό]

ENAME
DEPTNO
μž…μ‚¬μ›”
SAL

SMITH

20

12

800

ALLEN

30

2

1600

WARD

30

2

1250

JONES

20

4

2975

MARTIN

30

9

1250

BLAKE

30

5

2850

CLARK

10

6

2450

SCOTT

20

7

3000

KING

10

11

5000

TURNER

30

9

1500

ADAMS

20

7

1100

JAMES

30

12

950

FORD

20

12

3000

MILLER

10

1

1300

14 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

STEP2. 월별 데이터 ꡬ뢄

[예제] μΆ”μΆœλœ MONTH 데이터λ₯Ό Simple Case Expression을 μ΄μš©ν•΄μ„œ 12개의 월별 칼럼으둜 κ΅¬λΆ„ν•œλ‹€. μ‹€ν–‰ κ²°κ³Όμ—μ„œ 보여 μ£ΌλŠ” ENAME μΉΌλŸΌμ€ μ΅œμ’… λ¦¬ν¬νŠΈμ—μ„œ μš”κ΅¬λ˜λŠ” λ°μ΄ν„°λŠ” μ•„λ‹ˆμ§€λ§Œ, μ •λ³΄μ˜ 흐름을 μ΄ν•΄ν•˜κΈ° μœ„ν•΄ λΆ€κ°€μ μœΌλ‘œ 보여 μ£ΌλŠ” μž„μ‹œ 정보이닀. FROM μ ˆμ—μ„œ μ‚¬μš©λœ 인라인 λ·°λŠ” 2μž₯ 1μ ˆμ—μ„œ μ„€λͺ…ν•œλ‹€.

[예제]

SELECT ENAME
    , DEPTNO
    , CASE MONTH WHEN 1 THEN SAL END M01
    , CASE MONTH WHEN 2 THEN SAL END M02
    , CASE MONTH WHEN 3 THEN SAL END M03
    , CASE MONTH WHEN 4 THEN SAL END M04
    , CASE MONTH WHEN 5 THEN SAL END M05
    , CASE MONTH WHEN 6 THEN SAL END M06
    , CASE MONTH WHEN 7 THEN SAL END M07
    , CASE MONTH WHEN 8 THEN SAL END M08
    , CASE MONTH WHEN 9 THEN SAL END M09
    , CASE MONTH WHEN 10 THEN SAL END M10
    , CASE MONTH WHEN 11 THEN SAL END M11
    , CASE MONTH WHEN 12 THEN SAL END M12
 FROM ( SELECT ENAME, DEPTNO
             , EXTRACT( MONTH FROM HIREDATE ) MONTH SAL 
          FROM EMP );

[μ‹€ν–‰ κ²°κ³Ό]

ENAME
DEPTNO
M01
M02
M03
M04
M05
M06
M07
M08
M09
M10
M11
M12

SMITH

20

800

ALLEN

30

1600

WARD

30

1250

JONES

20

2975

MARTIN

30

1250

BLAKE

30

2850

CLARK

10

2450

SCOTT

20

3000

KING

10

5000

TURNER

30

1500

ADAMS

20

1100

JAMES

30

950

FORD

20

3000

MILLER

10

1300

14 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

STEP3. λΆ€μ„œλ³„ 데이터 집계

[예제] μ΅œμ’…μ μœΌλ‘œ λ³΄μ—¬μ£ΌλŠ” λ¦¬ν¬νŠΈλŠ” λΆ€μ„œλ³„λ‘œ 월별 μž…μ‚¬μžμ˜ 평균 κΈ‰μ—¬λ₯Ό μ•Œκ³  μ‹Άλ‹€λŠ” μš”κ΅¬ μ‚¬ν•­μ΄λ―€λ‘œ λΆ€μ„œλ³„ 평균값을 κ΅¬ν•˜κΈ° μœ„ν•΄ GROUP BY 절과 AVG 집계 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€. 직원 κ°œμΈμ— λŒ€ν•œ μ •λ³΄λŠ” 더 이상 ν•„μš” μ—†μœΌλ―€λ‘œ μ œμ™Έν•œλ‹€. ORDER BY μ ˆμ„ μ‚¬μš©ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— λΆ€μ„œλ²ˆν˜Έλ³„λ‘œ 정렬이 λ˜μ§€λŠ” μ•Šμ•˜λ‹€.

[예제]

SELECT DEPTNO
    , AVG( CASE MONTH WHEN  1 THEN SAL END ) M01
    , AVG( CASE MONTH WHEN  2 THEN SAL END ) M02
    , AVG( CASE MONTH WHEN  3 THEN SAL END ) M03
    , AVG( CASE MONTH WHEN  4 THEN SAL END ) M04
    , AVG( CASE MONTH WHEN  5 THEN SAL END ) M05
    , AVG( CASE MONTH WHEN  6 THEN SAL END ) M06
    , AVG( CASE MONTH WHEN  7 THEN SAL END ) M07
    , AVG( CASE MONTH WHEN  8 THEN SAL END ) M08
    , AVG( CASE MONTH WHEN  9 THEN SAL END ) M09
    , AVG( CASE MONTH WHEN 10 THEN SAL END ) M10
    , AVG( CASE MONTH WHEN 11 THEN SAL END ) M11
    , AVG( CASE MONTH WHEN 12 THEN SAL END ) M12
 FROM ( SELECT ENAME, DEPTNO
             , EXTRACT( MONTH FROM HIREDATE ) MONTH SAL
          FROM EMP )
GROUP BY DEPTNO;

[μ‹€ν–‰ κ²°κ³Ό]

DEPTNO
M01
M02
M03
M04
M05
M06
M07
M08
M09
M10
M11
M12

10

1300

2450

5000

20

2988

1100

1900

30

1425

2850

1375

950

3 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

ν•˜λ‚˜μ˜ 데이터에 μ—¬λŸ¬ 번 CASE ν‘œν˜„μ„ μ‚¬μš©ν•˜κ³  μ§‘κ³„ν•¨μˆ˜κ°€ μ μš©λ˜λ―€λ‘œ SQL 처리 μ„±λŠ₯ μΈ‘λ©΄μ—μ„œ λ‚˜μœ 것이 μ•„λ‹ˆλƒκ³  생각할 μˆ˜λ„ μžˆλ‹€. κ·Έλ ‡μ§€λ§Œ 같은 κΈ°λŠ₯을 ν•˜λŠ” 리포트λ₯Ό μž‘μ„±ν•˜κΈ° μœ„ν•΄ μž₯문의 ν”„λ‘œκ·Έλž¨μ„ μ½”λ”©ν•˜λŠ” 것에 λΉ„ν•΄, μœ„ 방법을 ν™œμš©ν•˜λ©΄ λ³΅μž‘ν•œ ν”„λ‘œκ·Έλž¨μ΄ μ•„λ‹Œ ν•˜λ‚˜μ˜ SQL λ¬Έμž₯으둜 처리 κ°€λŠ₯ν•˜λ―€λ‘œ DBMS μžμ› ν™œμš©μ΄λ‚˜ 처리 μ†λ„μ—μ„œ 훨씬 νš¨μœ¨μ μ΄λ‹€. 데이터 κ±΄μˆ˜κ°€ λ§Žμ•„μ§ˆμˆ˜λ‘ 처리 속도 차인느 더 λ‚  수 μžˆλ‹€. κ°œλ°œμžλ“€μ€ κ°€λŠ₯ν•œ ν•˜λ‚˜μ˜ SQL λ¬Έμž₯으둜 λΉ„μ¦ˆλ‹ˆμŠ€μ μΈ μš”κ΅¬ 사항을 μ²˜λ¦¬ν•  수 μžˆλ„λ‘ λ…Έλ ₯ν•΄μ•Ό ν•œλ‹€.

[예제] Simple Case Expression으둜 ν‘œν˜„λœ μœ„μ˜ SQLκ³Ό 같은 λ‚΄μš©μœΌλ‘œ Oracle의 DECODE ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œ SQL λ¬Έμž₯을 μž‘μ„±ν•œλ‹€.

[예제]

SELECT DEPTNO
    , AVG(DECODE(MONTH, 1, SAL)) M01
    , AVG(DECODE(MONTH, 2, SAL)) M02
    , AVG(DECODE(MONTH, 3, SAL)) M03
    , AVG(DECODE(MONTH, 4, SAL)) M04
    , AVG(DECODE(MONTH, 5, SAL)) M05
    , AVG(DECODE(MONTH, 6, SAL)) M06
    , AVG(DECODE(MONTH, 7, SAL)) M07
    , AVG(DECODE(MONTH, 8, SAL)) M08
    , AVG(DECODE(MONTH, 9, SAL)) M09
    , AVG(DECODE(MONTH, 10, SAL)) M10
    , AVG(DECODE(MONTH, 11, SAL)) M11
    , AVG(DECODE(MONTH, 12, SAL)) M12
 FROM (
   SELECT ENAME, DEPTNO
        , EXTRACT( MONTH FROM HIREDATE ) MONTH SAL
     FROM EMP )
GROUP BY DEPTNO;

DECODE ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•¨μœΌλ‘œμ¨ SQL λ¬Έμž₯이 쑰금 더 μ§§μ•„μ‘Œλ‹€. CASE ν‘œν˜„κ³Ό Oracle의 DECODE ν•¨μˆ˜λŠ” ν‘œν˜„μƒ μ„œλ‘œ μž₯단점이 μžˆμœΌλ―€λ‘œ μ–΄λ–€ κΈ°λŠ₯을 선택할 μ§€λŠ” μ‚¬μš©μžμ˜ λͺ«μ΄λ‹€.

5. 집계 ν•¨μˆ˜μ™€ NULL 처리

리포트의 λΉˆμΉΈμ„ NULL이 μ•„λ‹Œ ZERO둜 ν‘œν˜„ν•˜κΈ° μœ„ν•΄ NVL(Oracle)/ISNULL(SQL Server) ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°κ°€ λ§Žμ€λ°, 닀쀑 ν–‰ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°λŠ” 였히렀 λΆˆν•„μš”ν•œ λΆ€ν•˜κ°€ λ°œμƒν•˜λ―€λ‘œ ꡳ이 NVL ν•¨μˆ˜λ₯Ό 닀쀑 ν–‰ ν•¨μˆ˜ μ•ˆμ— μ‚¬μš©ν•  ν•„μš”κ°€ μ—†λ‹€. 닀쀑 ν–‰ ν•¨μˆ˜λŠ” μž…λ ₯ κ°’μœΌλ‘œ 전체 κ±΄μˆ˜κ°€ NULL 값인 경우만 ν•¨μˆ˜μ˜ κ²°κ³Όκ°€ NULL이 λ‚˜μ˜€κ³  전체 건수 μ€‘μ—μ„œ μΌλΆ€λ§Œ NULL인 κ²½μš°λŠ” NULL인 행을 닀쀑 ν–‰ ν•¨μˆ˜μ˜ λŒ€μƒμ—μ„œ μ œμ™Έν•œλ‹€. 예λ₯Ό λ“€λ©΄ 100λͺ… 쀑 10λͺ…μ˜ 성적이 NULL 값일 λ•Œ 평균을 κ΅¬ν•˜λŠ” 닀쀑 ν–‰ ν•¨μˆ˜ AVGλ₯Ό μ‚¬μš©ν•˜λ©΄ NULL 값이 μ•„λ‹Œ 90λͺ…μ˜ 성적에 λŒ€ν•΄μ„œ 평균값을 κ΅¬ν•˜κ²Œ λœλ‹€. CASE ν‘œν˜„ μ‚¬μš©μ‹œ ELSE μ ˆμ„ μƒλž΅ν•˜κ²Œ 되면 Default 값이 NULL이닀. NULL은 μ—°μ‚°μ˜ λŒ€μƒμ΄ μ•„λ‹Œ 반면, SUM(CASE MONTH WHEN 1 THEN SAL ELSE 0 END)처럼 ELSE μ ˆμ—μ„œ 0(Zero)을 μ§€μ •ν•˜λ©΄ λΆˆν•„μš”ν•˜κ²Œ 0이 SUM 연산에 μ‚¬μš©λ˜λ―€λ‘œ μžμ›μ˜ μ‚¬μš©μ΄ λ§Žμ•„μ§„λ‹€. 같은 κ²°κ³Όλ₯Ό 얻을 수 μžˆλ‹€λ©΄ κ°€λŠ₯ν•œ ELSE 절의 μƒμˆ˜κ°’μ„ μ§€μ •ν•˜μ§€ μ•Šκ±°λ‚˜ ELSE μ ˆμ„ μž‘μ„±ν•˜μ§€ μ•Šλ„λ‘ ν•œλ‹€. 같은 이유둜 Oracle의 DECODE ν•¨μˆ˜λŠ” 4번째 인자λ₯Ό μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ NULL이 Default둜 ν• λ‹Ήλœλ‹€. 많이 μ‹€μˆ˜ν•˜λŠ” 것 쀑에 ν•˜λ‚˜κ°€ Oracle의 SUM(NVL(SAL,0)), SQL Server의 SUM(ISNULL (SAL,0)) 연산이닀. κ°œλ³„ λ°μ΄ν„°μ˜ κΈ‰μ—¬(SAL)κ°€ NULL인 κ²½μš°λŠ” NULL의 νŠΉμ„±μœΌλ‘œ μžλ™μ μœΌλ‘œ SUM μ—°μ‚°μ—μ„œ λΉ μ§€λŠ” 데, λΆˆν•„μš”ν•˜κ²Œ NVL/ISNULL ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ 0(Zero)으둜 λ³€ν™˜μ‹œμΌœ 데이터 건수만큼의 연산이 μΌμ–΄λ‚˜κ²Œ ν•˜λŠ” 것은 μ‹œμŠ€ν…œμ˜ μžμ›μ„ λ‚­λΉ„ν•˜λŠ” 일이닀. 리포트 좜λ ₯ λ•Œ NULL이 μ•„λ‹Œ 0을 ν‘œμ‹œν•˜κ³  싢은 κ²½μš°μ—λŠ” NVL(SUM(SAL),0)μ΄λ‚˜, ISNULL(SUM(SAL),0)처럼 전체 SUM의 κ²°κ³Όκ°€ NULL인 경우(λŒ€μƒ κ±΄μˆ˜κ°€ λͺ¨λ‘ NULL인 경우)μ—λ§Œ ν•œ 번 NVL/ISNULL ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.

[예제] νŒ€λ³„ ν¬μ§€μ…˜λ³„ FW, MF, DF, GK ν¬μ§€μ…˜μ˜ μΈμ›μˆ˜μ™€ νŒ€λ³„ 전체 μΈμ›μˆ˜λ₯Ό κ΅¬ν•˜λŠ” SQL λ¬Έμž₯을 μž‘μ„±ν•œλ‹€. 데이터가 μ—†λŠ” κ²½μš°λŠ” 0으둜 ν‘œμ‹œν•œλ‹€.

[예제]

SIMPLE_CASE_EXPRESSION 쑰건 - Oracle

SELECT TEAM_ID
    , NVL(SUM(CASE POSITION WHEN 'FW' THEN 1 ELSE 0 END), 0) FW
    , NVL(SUM(CASE POSITION WHEN 'MF' THEN 1 ELSE 0 END), 0) MF
    , NVL(SUM(CASE POSITION WHEN 'DF' THEN 1 ELSE 0 END), 0) DF
    , NVL(SUM(CASE POSITION WHEN 'GK' THEN 1 ELSE 0 END), 0) GK
    , COUNT(*) SUM
 FROM PLAYER
GROUP BY TEAM_ID; 

[예제]

SIMPLE_CASE_EXPRESSION 쑰건 - Oracle CASE ν‘œν˜„μ˜ ELSE 0, ELSE NULL λ¬Έκ΅¬λŠ” μƒλž΅ κ°€λŠ₯ν•˜λ―€λ‘œ λ‹€μŒκ³Ό 같이 쑰금 더 짧게 SQL λ¬Έμž₯을 μž‘μ„±ν•  수 μžˆλ‹€.

Default 값인 NULL이 적용됨.

SELECT TEAM_ID
    , NVL(SUM(CASE POSITION WHEN 'FW' THEN 1 END), 0) FW
    , NVL(SUM(CASE POSITION WHEN 'MF' THEN 1 END), 0) MF
    , NVL(SUM(CASE POSITION WHEN 'DF' THEN 1 END), 0) DF
    , NVL(SUM(CASE POSITION WHEN 'GK' THEN 1 END), 0) GK
    , COUNT(*) SUM
 FROM PLAYER
GROUP BY TEAM_ID; 

[예제]

SEARCHED_CASE_EXPRESSION 쑰건 - Oracle

SELECT TEAM_ID
    , NVL(SUM(CASE WHEN POSITION = 'FW' THEN 1 END), 0) FW
    , NVL(SUM(CASE WHEN POSITION = 'MF' THEN 1 END), 0) MF
    , NVL(SUM(CASE WHEN POSITION = 'DF' THEN 1 END), 0) DF
    , NVL(SUM(CASE WHEN POSITION = 'GK' THEN 1 END), 0) GK
    , COUNT(*) SUM
 FROM PLAYER
GROUP BY TEAM_ID; 

[예제]

SEARCHED_CASE_EXPRESSION 쑰건 - SQL Server

SELECT TEAM_ID
    , ISNULL(SUM(CASE WHEN POSITION = 'FW' THEN 1 END), 0) FW
    , ISNULL(SUM(CASE WHEN POSITION = 'MF' THEN 1 END), 0) MF
    , ISNULL(SUM(CASE WHEN POSITION = 'DF' THEN 1 END), 0) DF
    , ISNULL(SUM(CASE WHEN POSITION = 'GK' THEN 1 END), 0) GK
    , COUNT(*) SUM
 FROM PLAYER
GROUP BY TEAM_ID; 

[μ‹€ν–‰ κ²°κ³Ό]

TEAM_ID
FW
MF
DF
GK
SUM

K14

0

1

1

0

2

K06

11

11

20

4

46

K13

1

0

1

1

3

K15

1

1

1

0

3

K02

10

18

17

4

49

K12

1

0

1

0

2

K04

13

11

18

4

46

K03

6

15

23

5

49

K07

9

22

16

4

51

K05

10

19

17

5

51

K08

8

15

15

4

45

K11

1

1

1

0

3

K01

12

15

13

5

45

K10

5

15

13

3

36

K09

12

18

15

4

49

15 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

4개의 예제 SQL λ¬Έμž₯은 같은 μ‹€ν–‰ κ²°κ³Όλ₯Ό 좜λ ₯ν•œλ‹€. ORDER BY 절이 μ μš©λ„μ§€ μ•Šμ•˜μœΌλ―€λ‘œ TEAM_IDλ³„λ‘œ 정렬돼 μžˆμ§€ μ•Šλ‹€. TEAM_ID 'K08'의 경우 POSITION이 NULL인 3건이 ν¬μ§€μ…˜λ³„ λΆ„λ₯˜μ—λŠ” λΉ μ Έ μžˆμ§€λ§Œ SUMμ—λŠ” μΆ”κ°€λ˜μ–΄ μžˆλ‹€. μ΄λŠ” TEAM_ID 'K08'의 각 POSITION의 합계(FW+MF+DF+GK)κ°€ 42건이고 SUM값이 45κ±΄μΈκ²ƒμœΌλ‘œ κ³„μ‚°ν• μˆ˜μžˆλ‹€(44-42=3).

[예제] GROUP BY 절 없이 전체 μ„ μˆ˜λ“€μ˜ ν¬μ§€μ…˜λ³„ 평균 ν‚€ 및 전체 평균 ν‚€λ₯Ό 좜λ ₯ν•  μˆ˜λ„ μžˆλ‹€.

[예제]

SELECT ROUND(AVG(CASE WHEN POSITION = 'MF' THEN HEIGHT END), 2) λ―Έλ“œν•„λ”
    , ROUND(AVG(CASE WHEN POSITION = 'FW' THEN HEIGHT END), 2) ν¬μ›Œλ“œ
    , ROUND(AVG(CASE WHEN POSITION = 'DF' THEN HEIGHT END), 2) λ””νŽœλ”
    , ROUND(AVG(CASE WHEN POSITION = 'GK' THEN HEIGHT END), 2) 골킀퍼
    , ROUND(AVG(HEIGHT), 2) 전체평균킀
 FROM PLAYER; 

[μ‹€ν–‰ κ²°κ³Ό]

λ―Έλ“œν•„λ”
ν¬μ›Œλ“œ
λ””νŽœλ”
골킀퍼
전체평균킀

176.31

179.91

180.21

186.26

179.31

1 개의 행이 μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

Previous2-1-4. WHERE 절Next2-1-6. ORDER BY 절

Last updated 3 years ago

Was this helpful?

좜처 : λ°μ΄ν„°μ˜¨μ—μ–΄ – ν•œκ΅­λ°μ΄ν„°μ‚°μ—…μ§„ν₯원()

😧
⭐
🌠
https://dataonair.or.kr