๐ ๋ณธ ํฌ์คํ ์์ ์ฌ์ฉ๋๋ ํ ์ด๋ธ์ ์๋ฃ์ ์ถ์ฒ๋ HackerRank ์์ ๋ฐํ๋๋ค. ๋ ๋ค์ํ SQL ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์๋ ค๋ฉดHackerRank ์ฌ์ดํธ๋ฅผ ๋ฐฉ๋ฌธํด ๋ณด์ธ์!
์ด๋ฒ ํฌ์คํ
์์๋ MySQL์ CASE WHEN
๊ตฌ๋ฌธ์ผ๋ก Pivot Table์ ๋ง๋ค์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์๊ฐํ๋ ค ํ๋ค. ํ์ฉํ๋ ค๋ ๋ฌธ์ ๋ HackerRank ์ฌ์ดํธ์ Occupations ๋ฌธ์ ์ด๋ค. ์๋ณธ์ ์ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ์.
์ฐ์ Pivot table์ด๋ ๋ฌด์์ผ๊น? ์ง๊ด์ ์ผ๋ก ๋งํ๋ฉด Row์ ์๋ ๊ฐ๋ค์ Column์ผ๋ก ๋ณํํ ํ
์ด๋ธ์ ๋งํ๋๋ฐ, Pandas์ pivot()
, pivot_table()
๋ฉ์๋๋ฅผ ํ์ฉํด๋ณธ ์ฌ๋๋ค์๊ฒ ์ต์ํ ๊ฒ์ด๋ค. Pivot table์ ํํ๋ ๋ค์๊ณผ ๊ฐ๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๊ฒ์ 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์ ์ดํด๋ณด์.
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๊ฐ์ง์ด๋ค.
- (Name์ ์ํ๋ฒณ์์ผ๋ก ์ ๋ ฌํ์ ๋)๊ฐ ์ง์ ๋ณ๋ก ์ฒซ ๋ฒ์งธ๋ก ์ค๋ Name๋ค, ๋ ๋ฒ์งธ๋ก ์ค๋ Name๋ค, ์ธ ๋ฒ์งธ๋ก ์ค๋ Name๋ค...(์๋ต)์ ์์๋ด๊ธฐ ์ํด SET ์ ์ด์ฉํด ๊ฐ ์ง์ ๋ณ์ Row๋ฅผ ์ธ์ด์ค๋ค.
- 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