HackerRank Occupations

JungWooLee·2022년 9월 6일
0

Database

목록 보기
1/2

문제

Pivot the Occupation column in OCCUPATIONS so that each Name is sorted alphabetically and displayed underneath its corresponding Occupation. The output column headers should be Doctor, Professor, Singer, and Actor, respectively.

Note: Print NULL when there are no more names corresponding to an occupation.

Input Format

The OCCUPATIONS table is described as follows:

Occupation will only contain one of the following values: Doctor, Professor, Singer or Actor.

Sample Input

Sample Output

Jenny    Ashley     Meera  Jane
Samantha Christeen  Priya  Julia
NULL     Ketty      NULL   Maria

Explanation

The first column is an alphabetically ordered list of Doctor names.
The second column is an alphabetically ordered list of Professor names.
The third column is an alphabetically ordered list of Singer names.
The fourth column is an alphabetically ordered list of Actor names.
The empty cell data for columns with less than the maximum number of names per occupation (in this case, the Professor and Actor columns) are filled with NULL values.


해석

pivot Table : 개별 항목을 집계 하는 그룹화된 값 테이블
즉, 요구사항으로 보았을 때 피봇 테이블을 사용하여 요구사항에 맞는 컬럼값을 가지도록 테이블을 만들고 이를 서브쿼리로 SELECT 해줘야 함을 알 수 있다

  1. Sample Output : row 는 이름순으로, col 은 순차적으로 Doctor, Professor, Singer, Actor 이다
  2. 문제의 요구사항에서 Occupation 에 해당하는 직업군은 위 네가지로 한정된다고 명시되어 있다
  3. 피봇 테이블이라는 힌트가 나왔을 때 집계 함수를 사용하여 group by를 사용해야 함을 알 수 있다

문제 풀이

1. 먼저 피봇 테이블을 생성한다

  • MySql, Oracle, teradata 등에서 사용되는 row_number() 내장 함수를 사용하여 집계 테이블을 생성

SQL문

SELECT  *, 
        ROW_NUMBER() OVER (PARTITION BY OCCUPATION ORDER BY NAME)
FROM OCCUPATIONS

  • Partition By : grouping을 통해 row_number를 계산하는데 활용
  • Order By : 그루핑된 테이블에서 이름을 기준으로 정렬

2. 피봇 테이블을 참조하는 테이블에서 만약 ROW 가 있을때 ROW의 순서대로 이름이 출력되도록 한다

  • EX ) 위 그림에서 ACTOR의 ROW는 1,2,3,4 / DOCTOR의 경우 1,2,3 이다. 이때 MIN() 을 사용하여 각 ROW 별로 이름을 출력해준다
  • MIN() 을 사용하는 이유는 만약 해당 칼럼이 없을때 NULL 이 반환되어야 하기 때문

최종 코드

SELECT  MIN(CASE WHEN OCCUPATION = 'DOCTOR' THEN NAME END),
        MIN(CASE WHEN OCCUPATION = 'PROFESSOR' THEN NAME END),
        MIN(CASE WHEN OCCUPATION = 'SINGER' THEN NAME END),
        MIN(CASE WHEN OCCUPATION = 'ACTOR' THEN NAME END)
FROM (
        SELECT  *, 
                ROW_NUMBER() OVER (PARTITION BY OCCUPATION ORDER BY NAME) AS R
        FROM OCCUPATIONS ) AS TMP
GROUP BY TMP.R
  • 최종적으로 group by 를 사용하여 피봇을 기준으로 그룹화시킨다

0개의 댓글