KEEP GOING

[MySQL] HackerRank : Occupations Solution 본문

code review/sql

[MySQL] HackerRank : Occupations Solution

jmHan 2021. 12. 23. 18:37
반응형

 

 

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

 

Occupations | HackerRank

Pivot the Occupation column so the Name of each person in OCCUPATIONS is displayed underneath their respective Occupation.

www.hackerrank.com

 

 

1. 에러난 코드 

SELECT (CASE WHEN Occupation LIKE 'D%' THEN Name END)AS Docter
        , (CASE WHEN Occupation LIKE 'P%' THEN Name END)AS Professor
        , (CASE WHEN Occupation LIKE 'S%' THEN Name END)AS Singer
        , (CASE WHEN Occupation LIKE 'A%' THEN Name END) AS Actor
FROM OCCUPATIONS
ORDER BY Docter DESC, Professor DESC, Singer DESC, Actor DESC

 

문제에서 요구하는 바에 의하면 출력값이 아래와 같이 나와야 한다.

 

ORDER BY Docter DESC, Professor DESC, Singer DESC, Actor DESC

 

해당 order by절을 해석해 보자면 Doctor 값이 같으면 (ex. NULL) Professor 값으로 정렬되고, Professor 값이 같다면 Singer 값으로 정렬된다 ...  

 

 

문제를 해결하기 위해서는 각 직업별 이름 순으로 번호를 매겨주어야 한다. 번호를 매기는 방법은 컬럼 절에서 서브쿼리로 직업별 이름순으로 순위를 부여하는 컬럼을 생성하면 된다. 

 

 

SELECT a.Occupation as Occupation

          ,a.Name as Name

          ,(SELECT COUNT(*) 
            FROM Occupations AS b
            WHERE a.Occupation = b.Occupation AND a.Name > b.Name) as Rank
FROM Occupations AS a
ORDER BY a.Occupation, a.Name

 

위 쿼리를 실행하면 다음과 같은  테이블이 조회된다.

 

2. 정답인 코드 

SELECT MIN(CASE WHEN Occupation LIKE 'D%' THEN Name END)AS Docter
     , MIN(CASE WHEN Occupation LIKE 'P%' THEN Name END)AS Professor
     , MIN(CASE WHEN Occupation LIKE 'S%' THEN Name END)AS Singer
     , MIN(CASE WHEN Occupation LIKE 'A%' THEN Name END)AS Actor
FROM (
SELECT a.Occupation as Occupation,
         a.Name as Name,
         (SELECT COUNT(*) 
            FROM Occupations AS b
            WHERE a.Occupation = b.Occupation AND a.Name > b.Name) as Rank_num
FROM Occupations AS a
ORDER BY a.Occupation, a.Name ) as tmp
GROUP BY tmp.Rank_num

 

MIN() 함수를 이용하면 Rank 값을 기준으로 NULL 값이 아닌 최솟값부터 차례로 출력할 수 있다. 

 

반응형
Comments