๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

SQL

[SQL] CASE WHEN์œผ๋กœ Pivot Table ๋งŒ๋“ค๊ธฐ(HackerRank - Occupations ๋ฌธ์ œ)

๋ฐ˜์‘ํ˜•

๐Ÿ”Š ๋ณธ ํฌ์ŠคํŒ…์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ…Œ์ด๋ธ”์˜ ์ž๋ฃŒ์™€ ์ถœ์ฒ˜๋Š” HackerRank ์ž„์„ ๋ฐํž™๋‹ˆ๋‹ค. ๋” ๋‹ค์–‘ํ•œ SQL ๋ฌธ์ œ๋ฅผ ํ’€์–ด๋ณด์‹œ๋ ค๋ฉดHackerRank ์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•ด ๋ณด์„ธ์š”!

 

HackerRank ์‚ฌ์ดํŠธ

 

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” MySQL์˜ CASE WHEN ๊ตฌ๋ฌธ์œผ๋กœ Pivot Table์„ ๋งŒ๋“ค์–ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•˜๋ ค ํ•œ๋‹ค. ํ™œ์šฉํ•˜๋ ค๋Š” ๋ฌธ์ œ๋Š” HackerRank ์‚ฌ์ดํŠธ์˜ Occupations ๋ฌธ์ œ์ด๋‹ค. ์›๋ณธ์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์ž.

 

์šฐ์„  Pivot table์ด๋ž€ ๋ฌด์—‡์ผ๊นŒ? ์ง๊ด€์ ์œผ๋กœ ๋งํ•˜๋ฉด Row์— ์žˆ๋Š” ๊ฐ’๋“ค์„ Column์œผ๋กœ ๋ณ€ํ˜•ํ•œ ํ…Œ์ด๋ธ”์„ ๋งํ•˜๋Š”๋ฐ, Pandas์˜ pivot(), pivot_table() ๋ฉ”์†Œ๋“œ๋ฅผ ํ™œ์šฉํ•ด๋ณธ ์‚ฌ๋žŒ๋“ค์—๊ฒ ์ต์ˆ™ํ•  ๊ฒƒ์ด๋‹ค. Pivot table์˜ ํ˜•ํƒœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

์ถœ์ฒ˜ : Pandas documentation

 

๊ทธ๋ ‡๋‹ค๋ฉด ์ด๊ฒƒ์„ CASE WHEN ๊ตฌ๋ฌธ์œผ๋กœ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์ค„ ์ˆ˜ ์žˆ์„๊นŒ? ๋ฌธ์ œ๋ฅผ ๋ณด๋ฉด์„œ ๊ฐ™์ด ์‚ดํŽด๋ณด์ž. ๋ฌธ์ œ์˜ ์š”๊ตฌ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

PivottheOccupationcolumn inOCCUPATIONSso that eachNameis sorted alphabetically and displayed underneath its correspondingOccupation. The output column headers should beDoctor,Professor,Singer, andActor, respectively. Note:PrintNULLwhen there are no more names corresponding to an occupation.
(๊ฐ๊ฐ์˜ ์ด๋ฆ„์„ ์•ŒํŒŒ๋ฒณ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๊ณ  ๊ทธ์— ์ƒ์‘ํ•˜๋Š” ์ง์—…(Occupation)์„ ๋ณด์—ฌ์ฃผ๋Š”๋ฐ, ์ง์—…๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ Pivot ํ…Œ์ด๋ธ”๋กœ ๋ณ€ํ™˜ํ•ด๋ผ. ์ด ๋•Œ ๋ณ€ํ™˜ํ•œ Pivot ํ…Œ์ด๋ธ”์˜ ์นผ๋Ÿผ๋ช…์€ Doctor, Professor, Singer, Actor ์ˆœ์ด๋‹ค. ์ฐธ๊ณ ๋กœ, ๊ฐ ์ง์—…์— ๋Œ€์‘ํ•˜๋Š” ์ด๋ฆ„์ด ์—†๋‹ค๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•ด๋ผ.)

์œ„ ๊ธ€์˜ ์„ค๋ช…๋งŒ ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ Sample Input/Output์„ ์‚ดํŽด๋ณด์ž.

 

Occupations ๋ฌธ์ œ์˜ ์ƒ˜ํ”Œ I/O

 

Input ํ…Œ์ด๋ธ”์„ ์‚ดํŽด๋ณด์•˜์„ ๋•Œ, Occupation ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๊ฐ๊ฐ์— ์†ํ•˜๋Š” Name๋“ค์„ ์ •๋ฆฌํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.(Name์€ ์•ŒํŒŒ๋ฒณ ์ˆœ์œผ๋กœ ์ •๋ ฌํ–ˆ๋‹ค.)

 

  • Doctor : Jenny, Samantha
  • Professor : Ashely, Christeen, Ketty
  • Singer : Meera, Priya
  • Actor : Jane, Julia, Maria

์ด ๋•Œ, ๊ฐ ์ง์—…์— ์†ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ด๋ฆ„๋“ค๋ผ๋ฆฌ ํ•œ ํ–‰์— ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ๊ทธ index์— ํ•ด๋‹นํ•˜๋Š” ์ง์—…์˜ ์ด๋ฆ„์ด ์—†๋‹ค๋ฉด Null์„ ์ถœ๋ ฅํ•˜๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ Sample Output์„ Pivot ํ˜•ํƒœ๋กœ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

Doctor Professor Singer Actor
Jenny Ashely Meera Jane
Samantha Christeen Priya Julia
NULL Ketty NULL Maria

 

๋งŒ์•ฝ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์—ฌ๊ธฐ Discussion์—์„œ ๋‹‰๋„ค์ž„ raiyanger24์˜ Step๋ณ„ ํ’€์ด๋ฐฉ๋ฒ•๊ณผ ์ด ์ด๋ฏธ์ง€๋ฅผ ์ฐธ์กฐํ•ด๋ณด์ž.

SQL ํ’€์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

-- ๊ฐ ์ง์—…๋ณ„ Index๋ฅผ ์„ธ๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜ ์„ค์ •
SET @D=0, @P=0, @S=0, @A=0;

-- ๋ฌธ์ž์—ด์˜ ์•ŒํŒŒ๋ฒณ์ˆœ์„œ์—์„œ ์ตœ์†Ÿ๊ฐ’(MIN)์€ A(a)๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ถœํ•ด์คŒ!
SELECT MIN(Doctor), MIN(Professor), MIN(Singer), MIN(Actor)
FROM (SELECT CASE WHEN Occupation = 'Doctor' THEN Name END AS Doctor,
             CASE WHEN Occupation = 'Professor' THEN Name END AS Professor,
             CASE WHEN Occupation = 'Singer' THEN Name END AS Singer,
             CASE WHEN Occupation = 'Actor' THEN Name END AS Actor,
             CASE
             WHEN Occupation = 'Doctor' THEN (@D:=@D+1)
             WHEN Occupation = 'Professor' THEN (@P:=@P+1)
             WHEN Occupation = 'Singer' THEN (@S:=@S+1)
             WHEN Occupation = 'Actor' THEN (@A:=@A+1)
             END AS RowNumber
       FROM Occupations
       ORDER BY Name) sub
GROUP BY RowNumber

 

์œ„ ํ’€์ด์˜ ํ•ต์‹ฌ ํฌ์ธํŠธ๋Š” 2๊ฐ€์ง€์ด๋‹ค.

 

  1. (Name์„ ์•ŒํŒŒ๋ฒณ์ˆœ์œผ๋กœ ์ •๋ ฌํ–ˆ์„ ๋•Œ)๊ฐ ์ง์—…๋ณ„๋กœ ์ฒซ ๋ฒˆ์งธ๋กœ ์˜ค๋Š” Name๋“ค, ๋‘ ๋ฒˆ์งธ๋กœ ์˜ค๋Š” Name๋“ค, ์„ธ ๋ฒˆ์งธ๋กœ ์˜ค๋Š” Name๋“ค...(์ƒ๋žต)์„ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•ด SET ์„ ์ด์šฉํ•ด ๊ฐ ์ง์—…๋ณ„์˜ Row๋ฅผ ์„ธ์–ด์ค€๋‹ค.
  2. CASE WHEN์„ ์‚ฌ์šฉํ•ด Row์˜ ๊ฐ’์„ Column์œผ๋กœ Pivot table์„ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ

์šฐ์„  SQL ๊ตฌ๋ฌธ ํ•˜๋‚˜ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณด๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์‚ดํŽด๋ณด์ž. ํ•˜๋‹จ์˜ SQL ๊ตฌ๋ฌธ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ ํฌ๋งท์ด ๋‚˜์˜จ๋‹ค.

 

SELECT CASE WHEN Occupation = 'Doctor' THEN Name END AS Doctor,
       CASE WHEN Occupation = 'Professor' THEN Name END AS Professor,
       CASE WHEN Occupation = 'Singer' THEN Name END AS Singer,
       CASE WHEN Occupation = 'Actor' THEN Name END AS Actor
FROM Occupations
ORDER BY Name

 

๊ฒฐ๊ณผ ํ™”๋ฉด

 

์œ„ ๊ฒฐ๊ณผํ™”๋ฉด์„ ๋ณด๋ฉด ์ง์—…๋ณ„๋กœ Pivot ํ…Œ์ด๋ธ” ํ˜•ํƒœ๋Š” ๋งŒ๋“ค์–ด์กŒ์ง€๋งŒ ๊ฐ ์ง์—…๋ณ„๋กœ ๋™์ผํ•œ index ์ˆœ์„œ๋กœ ์˜ค๋Š” Name๋“ค์„ ํ•˜๋‚˜์˜ ํ–‰์— ์œ„์น˜์‹œํ‚ค์ง€ ๋ชปํ•˜๊ณ  ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ง์—…์ด Doctor์ด๋ฉด์„œ ์•ŒํŒŒ๋ฒณ์ˆœ์œผ๋กœ ๊ฐ€์žฅ ์ฒซ ๋ฒˆ์งธ์˜ค๋Š” Name์€ Aamina ์ด๊ณ  Professor์€ Ashley, Singer์€ Christeen, Actor์€ Eve์ด๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ํ˜•ํƒœ๋Š” ํ•œ Row์— ์ด ์ด๋ฆ„๋“ค์ด ๋ชจ๋‘ ๋“ค์–ด ์žˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ์ด๋‹ค.

 

Doctor Professor Singer Actor
Aamina Ashley Christeen Eve

 

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ Row์— ์ง์—…๋ณ„ ๋™์ผํ•œ index์ธ Name๋“ค๋ผ๋ฆฌ ๋ชจ์œผ๊ธฐ ์œ„ํ•ด SET์„ ์ด์šฉํ•ด ๊ฐ ์ง์—…๋ณ„ ํ–‰ index๋ฅผ ์„ธ๋ฉด์„œ ์„ค์ •ํ•ด์ฃผ์ž. ๋‹ค์Œ SQL ๊ตฌ๋ฌธ์˜ ๊ฒฐ๊ณผํ™”๋ฉด์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

-- ๊ฐ ์ง์—…๋ณ„ Index๋ฅผ ์„ธ๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜ ์„ค์ •
SET @D=0, @P=0, @S=0, @A=0;

SELECT Name,
       Occupation,
       CASE 
       WHEN Occupation = 'Doctor' THEN (@D:=@D+1)
       WHEN Occupation = 'Professor' THEN (@P:=@P+1)
       WHEN Occupation = 'Singer' THEN (@S:=@S+1)
       WHEN Occupation = 'Actor' THEN (@A:=@A+1)
       END AS RowNumber
FROM Occupations

 

๊ฒฐ๊ณผํ™”๋ฉด

 

์œ„ ๊ฒฐ๊ณผํ™”๋ฉด์„ ์‚ดํŽด๋ณด๋ฉด ์ง์—…๋ณ„๋กœ Row index๊ฐ€ ๋งค๊ฒจ์ ธ ์žˆ์Œ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด์ œ ์œ„ 2๊ฐœ์˜ SQL ๊ตฌ๋ฌธ์„ ํ•ฉ์ณ ์ถœ๋ ฅํ•œ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

-- ๊ฐ ์ง์—…๋ณ„ Index๋ฅผ ์„ธ๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜ ์„ค์ •
SET @D=0, @P=0, @S=0, @A=0;

-- ๋ฌธ์ž์—ด์˜ ์•ŒํŒŒ๋ฒณ์ˆœ์„œ์—์„œ ์ตœ์†Ÿ๊ฐ’(MIN)์€ A(a)๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ถœํ•ด์คŒ!
SELECT CASE WHEN Occupation = 'Doctor' THEN Name END AS Doctor,
       CASE WHEN Occupation = 'Professor' THEN Name END AS Professor,
       CASE WHEN Occupation = 'Singer' THEN Name END AS Singer,
       CASE WHEN Occupation = 'Actor' THEN Name END AS Actor,
       CASE
       WHEN Occupation = 'Doctor' THEN (@D:=@D+1)
       WHEN Occupation = 'Professor' THEN (@P:=@P+1)
       WHEN Occupation = 'Singer' THEN (@S:=@S+1)
       WHEN Occupation = 'Actor' THEN (@A:=@A+1)
       END AS RowNumber
FROM Occupations
ORDER BY Name

 

๊ฒฐ๊ณผํ™”๋ฉด

 

์œ„ ๊ฒฐ๊ณผ ์ƒํƒœ์—์„œ ์ด์ œ RowNumber๋ผ๋Š” ์ƒˆ๋กœ์šด ํŒŒ์ƒ ์นผ๋Ÿผ์„ ๊ธฐ์ค€์œผ๋กœ ๊ทธ๋ฃนํ•‘ํ•œ ํ›„ ๊ฐ ์ง์—…๋ณ„ Name๋“ค์˜ ์ตœ์†Ÿ๊ฐ’์„ ์ถœ๋ ฅํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ํ˜•ํƒœ๋กœ ์ถœ๋ ฅ๋œ๋‹ค.

 

-- ๊ฐ ์ง์—…๋ณ„ Index๋ฅผ ์„ธ๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜ ์„ค์ •
SET @D=0, @P=0, @S=0, @A=0;

-- ๋ฌธ์ž์—ด์˜ ์•ŒํŒŒ๋ฒณ์ˆœ์„œ์—์„œ ์ตœ์†Ÿ๊ฐ’(MIN)์€ A(a)๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ถœํ•ด์คŒ!
SELECT MIN(Doctor), MIN(Professor), MIN(Singer), MIN(Actor)
FROM (SELECT CASE WHEN Occupation = 'Doctor' THEN Name END AS Doctor,
             CASE WHEN Occupation = 'Professor' THEN Name END AS Professor,
             CASE WHEN Occupation = 'Singer' THEN Name END AS Singer,
             CASE WHEN Occupation = 'Actor' THEN Name END AS Actor,
             CASE
             WHEN Occupation = 'Doctor' THEN (@D:=@D+1)
             WHEN Occupation = 'Professor' THEN (@P:=@P+1)
             WHEN Occupation = 'Singer' THEN (@S:=@S+1)
             WHEN Occupation = 'Actor' THEN (@A:=@A+1)
             END AS RowNumber
       FROM Occupations
       ORDER BY Name) sub
GROUP BY RowNumber

 

๊ฒฐ๊ณผํ™”๋ฉด

 

๋ฐ˜์‘ํ˜•