[TIL] MySQL TIL Day 6

2 ๋ถ„ ์†Œ์š”

๐ŸŸก [HackerRank] Occupations

https://www.hackerrank.com/challenges/occupations/problem?isFullScreen=true

Solution

์ด ๋ฌธ์ œ๋Š” mySQL์˜ CASE WHEN์„ ์ด์šฉํ•˜์—ฌ pivot table๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค. Pivot table์€ ๊ฐ„๋‹จํžˆ ๋งํ•˜๋ฉด ํ…Œ์ด๋ธ”์˜ Row๋ฅผ Column์œผ๋กœ ๋ณ€ํ˜•ํ•œ ํ…Œ์ด๋ธ”์ด๋‹ค.

(1) Step 1: CASE WHEN ์œผ๋กœ Name๊ณผ Null ๋ถ€์—ฌ

์ฒซ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” CASE WHEN์„ ์ด์šฉํ•ด Occupation์ด ํŠน์ • ์ง์ข…(Doctor ๋“ฑ๋“ฑ) ์ด๋ผ๋ฉด Name์„, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด Null๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฌธ์ œ์—์„œ ์ œ์‹œํ•œ๋Œ€๋กœ Name์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.

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

์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค. ๋ณธ ๋ฌธ์ œ๋Š” ๊ฐ Occupation์„ ์นผ๋Ÿผ์œผ๋กœ ๋‘๊ณ  1ํ–‰๋ถ€ํ„ฐ ํ•ด๋‹นํ•˜๋Š” Name์ด ๊ฐ๊ฐ ์ฐจ๋ก€๋Œ€๋กœ ์นผ๋Ÿผ์— ์ž…๋ ฅ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋ฉด ์•ˆ๋œ๋‹ค.

Aamina NULL NULL NULL
NULL Ashley NULL NULL
NULL Belvet NULL NULL
NULL Britney NULL NULL
NULL NULL Christeen NULL
NULL NULL NULL Eve
NULL NULL Jane NULL
NULL NULL NULL Jennifer
NULL NULL Jenny NULL

(2) Step 2: Row number ๋ถ€์—ฌ

Step 1์—์„œ ์ œ์‹œํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ row์— row number์„ ๋ถ€์—ฌํ•œ๋‹ค. ์ด ๋•Œ ๊ฐ occupation์— ๋Œ€ํ•ด row number์„ ๋ถ€์—ฌํ•ด์•ผํ•œ๋‹ค. ๊ทธ๋ž˜์•ผ ๊ฐ occupation์˜ ์ฒซ๋ฒˆ์งธ Name์„ ์ฒซ ๋ฒˆ์งธ row์—์„œ ๋™์‹œ์— ์‹œ์ž‘ํ•˜๊ฒŒ ๋‘˜ ์ˆ˜ ์žˆ๋‹ค. TIL Day 5์—์„œ ๋‹ค๋ฃฌ SET์„ ์ด์šฉํ•œ ํŒŒ์ƒ๋ณ€์ˆ˜ ์ƒ์„ฑ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค. ๊ฐ Occupation์˜ row number์„ ์ •์˜ํ•˜๋Š” ํŒŒ์ƒ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

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

๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค. Professor ์ค‘์—์„œ Ashley, Britney, Maria, Meera ์ˆœ์œผ๋กœ row number๊ฐ€ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ๋ถ€์—ฌ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Ashley Professor 1
Samantha Actor 1
Julia Doctor 1
Britney Professor 2
Maria Professor 3
Meera Professor 4
Priya Doctor 2

(3) Step 3: ํ•ฉ์น˜๊ธฐ ๋ฐ Group by

์ด์ œ Step 1๊ณผ Step 2๋ฅผ ํ•ฉ์ณ FROM ์ ˆ์˜ ์„œ๋ธŒ์ฟผ๋ฆฌ๋กœ ๋„ฃ์–ด์ค€๋‹ค. ๊ทธ ๋‹ค์Œ Group by๋ฅผ ์ด์šฉํ•ด row number ๊ธฐ์ค€์œผ๋กœ grouping ํ•˜๋ฉด ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ์ด ๋•Œ Group by๋Š” ๋ฌด์กฐ๊ฑด ์ง‘๊ณ„ํ•จ์ˆ˜์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, ๋ณธ ๋ฌธ์ œ์—์„œ๋Š” ์ง‘๊ณ„ํ•  ๊ฑด ์—†์œผ๋ฏ€๋กœ ์•„๋ฌด ์˜๋ฏธ ์—†๋Š” MIN์ด๋‚˜ MAX๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

SET @D = 0, @P = 0, @S = 0, @A = 0;

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) AS t
GROUP BY rownumber

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ