SQL - Pivot

ํ˜ธ์ดยท2025๋…„ 12์›” 15์ผ

๐Ÿ“˜ SQL์—์„œ ๊ธฐ์ค€ ๊ฐ’์— ๋”ฐ๋ผ ํ‰๊ท ์„ ์ปฌ๋Ÿผ์œผ๋กœ ํŽผ์น˜๋Š” ํŒจํ„ด (Pivot)

๋ฐ์ดํ„ฐ๋ฅผ ์ง‘๊ณ„ํ•˜๋‹ค ๋ณด๋ฉด
๊ธฐ์ค€ ๊ฐ’(์—ฐ๋„, ๋ถ„๊ธฐ, ์ƒํƒœ๊ฐ’ ๋“ฑ)์— ๋”ฐ๋ผ ํ‰๊ท ์„ ๊ตฌํ•œ ๋’ค
์ด๋ฅผ ์ปฌ๋Ÿผ ํ˜•ํƒœ๋กœ ํŽผ์ณ์„œ ๋ณด๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

๋‹จ์ˆœ ์ง‘๊ณ„์™€๋Š” ๋‹ค๋ฅด๊ฒŒ,
๊ฒฐ๊ณผ ํ˜•ํƒœ๋ฅผ ํ•œ ๋ฒˆ ๋” ๋ณ€ํ˜•ํ•ด์•ผ ํ•˜๋Š” ํŒจํ„ด์ด๋ผ ์ •๋ฆฌํ•ด ๋‘”๋‹ค.


1. ๊ธฐ๋ณธ ํ˜•ํƒœ โ€” ๊ธฐ์ค€ ๊ฐ’๋ณ„ ํ‰๊ท  ๊ณ„์‚ฐ

์•„๋ž˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์ง‘๊ณ„ ํ˜•ํƒœ๋‹ค.

SELECT
    category,
    ๊ธฐ์ค€๊ฐ’,
    ROUND(AVG(score), 2) AS avg_score
FROM data_table
WHERE ๊ธฐ์ค€๊ฐ’ BETWEEN A AND B
  AND score IS NOT NULL
GROUP BY category, ๊ธฐ์ค€๊ฐ’;

์ด ์ฟผ๋ฆฌ๋Š”
์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ยท๊ธฐ์ค€๊ฐ’๋ณ„ ํ‰๊ท ์„ ๊ณ„์‚ฐํ•œ๋‹ค.

๊ฒฐ๊ณผ ํ˜•ํƒœ๋Š” ๋Œ€๋žต ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

category๊ธฐ์ค€๊ฐ’avg_score
A178.32
A280.15
A379.40
โ€ฆโ€ฆโ€ฆ

์ง‘๊ณ„ ์ž์ฒด๋Š” ๋ฌธ์ œ์—†์ง€๋งŒ,
๊ธฐ์ค€๊ฐ’์„ ํ•œ๋ˆˆ์— ๋น„๊ตํ•˜๊ธฐ์—๋Š” ๋‹ค์†Œ ๋ถˆํŽธํ•˜๋‹ค.


2. ํ•„์š”ํ•œ ๋ณ€ํ˜• โ€” ๊ธฐ์ค€๊ฐ’์„ ์ปฌ๋Ÿผ์œผ๋กœ ํŽผ์น˜๊ธฐ

์ด๋Ÿฐ ๊ฒฝ์šฐ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋Š” ๋ณดํ†ต ์•„๋ž˜ ํ˜•ํƒœ๋‹ค.

categoryscore_1score_2score_3score_4score_5

์ฆ‰,

  • ๊ธฐ์ค€๊ฐ’์€ ํ–‰์ด ์•„๋‹ˆ๋ผ ์ปฌ๋Ÿผ
  • category ๋‹น ํ•œ ํ–‰
  • ๊ธฐ์ค€๊ฐ’๋ณ„ ํ‰๊ท ์€ ๊ฐ ์ปฌ๋Ÿผ์— ์œ„์น˜

์ด ํŒจํ„ด์„ ํ”ํžˆ pivot ํ˜•ํƒœ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.


3. CASE WHEN์„ ์ด์šฉํ•œ ์กฐ๊ฑด๋ถ€ ์ง‘๊ณ„

MySQL๊ณผ PostgreSQL ๋ชจ๋‘์—์„œ
๊ฐ€์žฅ ๋ฒ”์šฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€
CASE WHEN์„ ์ด์šฉํ•œ ์กฐ๊ฑด๋ถ€ ์ง‘๊ณ„๋‹ค.

SELECT
    category,
    ROUND(AVG(CASE WHEN ๊ธฐ์ค€๊ฐ’ = 1 THEN score END), 2) AS score_1,
    ROUND(AVG(CASE WHEN ๊ธฐ์ค€๊ฐ’ = 2 THEN score END), 2) AS score_2,
    ROUND(AVG(CASE WHEN ๊ธฐ์ค€๊ฐ’ = 3 THEN score END), 2) AS score_3,
    ROUND(AVG(CASE WHEN ๊ธฐ์ค€๊ฐ’ = 4 THEN score END), 2) AS score_4,
    ROUND(AVG(CASE WHEN ๊ธฐ์ค€๊ฐ’ = 5 THEN score END), 2) AS score_5
FROM data_table
WHERE ๊ธฐ์ค€๊ฐ’ BETWEEN 1 AND 5
  AND score IS NOT NULL
GROUP BY category
ORDER BY category;

์ปฌ๋Ÿผ๋ช…๊ณผ ํ…Œ์ด๋ธ”๋ช…์€ ์˜ˆ์‹œ์ด๋ฉฐ,
ํŠน์ • ๋ฐ์ดํ„ฐ์…‹์„ ์ง์ ‘ ๋“œ๋Ÿฌ๋‚ด์ง€ ์•Š๋Š” ์ผ๋ฐ˜์ ์ธ ํ˜•ํƒœ๋‹ค.


4. ๋™์ž‘ ์›๋ฆฌ ์ •๋ฆฌ

CASE WHEN ๊ธฐ์ค€๊ฐ’ = 1 THEN score END
  • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด score ๋ฐ˜ํ™˜
  • ์•„๋‹ˆ๋ฉด NULL ๋ฐ˜ํ™˜
AVG(...)
  • AVG๋Š” NULL์„ ์ž๋™์œผ๋กœ ์ œ์™ธ
  • ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ•ด๋‹น ๊ธฐ์ค€๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ํ‰๊ท ๋งŒ ๊ณ„์‚ฐ

์ด๋ฅผ ๊ธฐ์ค€๊ฐ’๋ณ„๋กœ ๋ฐ˜๋ณตํ•˜๋ฉด
๊ธฐ์ค€๊ฐ’์ด ์ปฌ๋Ÿผ์œผ๋กœ ํŽผ์ณ์ง„ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.


5. DB๋ณ„ ๊ณตํ†ต ์‚ฌํ•ญ

  • MySQL โ†’ CASE WHEN + AVG
  • PostgreSQL โ†’ CASE WHEN + AVG

(PostgreSQL์—๋Š” FILTER ๋ฌธ๋ฒ•๋„ ์žˆ์ง€๋งŒ,
์ผ๋ฐ˜์ ์ธ ํŒจํ„ด ์ •๋ฆฌ์—๋Š” CASE WHEN์ด ๊ฐ€์žฅ ๋ณดํŽธ์ ์ด๋‹ค.)


6. ์ •๋ฆฌ

  • ์ปฌ๋Ÿผ์ด ๊ณ ์ •๋œ ๊ฒฝ์šฐ์—๋Š”
    CASE WHEN์„ ๋ช…์‹œ์ ์œผ๋กœ ๋‚˜์—ดํ•˜๋Š” ๋ฐฉ์‹์ด ๊ฐ€์žฅ ๋ช…ํ™•ํ•˜๋‹ค.

7. ๋งˆ๋ฌด๋ฆฌ

Sql์—์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ”ผ๋ฒ— ํ˜•ํƒœ ์ถœ๋ ฅํ•ด๋ณด๊ธฐ์— ์ ์ ˆํ•˜๋‹ค.
๋‹ค๋งŒ, ์—ด์ด ๋Š˜์–ด๋‚ ์ˆ˜๋กœ ๋น„ํšจ์œจ์ ์ด๋ฏ€๋กœ ๋‹ค๋ฅธ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

profile
ํ˜ธ์ž‡

0๊ฐœ์˜ ๋Œ“๊ธ€