본문 바로가기
Database/Oracle

[Oracle] 해커랭크(HackerRank) 문제 풀이 - Occupations

by 백종원흑종원 2023. 3. 22.

<문제>

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: DoctorProfessorSinger 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.

 

문제 정리

1. OCCUPATIONS 테이블은 이름, 직업 두 컬럼으로 구성되어있고 직업은 무작위로 섞여있다

2. 직업별로 컬럼을 만들어 해당 직업에 해당하는 사람들을 한 컬럼에 모아야한다(피벗)

3. 행의 수는 어떤 한 직업에 해당하는 최대 인원 수 만큼 생성될 것이다 인원 수가 부족한 직업은 NULL로 채워진다

ex: 의사 5명, 교수 2명 이라면 행은 5개가 될 것이고 의사 튜플은 전부 채워지겠지만 교수 튜플은 3개가 NULL이 될 것이다

4. 이름을 알파벳 순으로 정렬해야한다

 

문제 풀이

 

OCCUPATIONS 테이블:

SELECT Name,
       Occupation,
       ROW_NUMBER() OVER (PARTITION BY Occupation ORDER BY Name) AS OCC_NUM
FROM OCCUPATIONS;

먼저 위 쿼리를 실행해보면

<예시1>

 

<예시1>처럼 무작위로 섞여있던 데이터들이 직업별로 묶이고 이름은 a,b,c순 으로 정렬되어 OCC_NUM 컬럼에

번호가 채번된다

*SQL문장 안에 SQL 문장을 삽입해서 사용 하는 것을 '서브쿼리' 라고 한다,

*우리는 서브쿼리를 FROM 절에서 사용할 것이며 FROM절에서 사용되는 서브쿼리는 '인라인 뷰' 라고 함

 

오라클의 PIVOT 함수를 사용하면

<예시2>의 그림처럼 직업의 종류를 열로 만들 수 있고 각 직업별 번호에 따라서 출력할 수 있다

 

SELECT * 
FROM
    (SELECT Name,
           Occupation,
           ROW_NUMBER() OVER (PARTITION BY Occupation ORDER BY Name) AS OCC_NUM
    FROM OCCUPATIONS)
PIVOT
    (MAX(Name)
    FOR Occupation IN ('Doctor' AS Doctor, 'Professor' AS Professor,'Singer' AS Singer,'Actor' AS Actor));

PIVOT
    (MAX(Name)  -> PIVOT을 사용할때는 문법상 합계함수를 함께 사용해야함 (우리는 직업과, OCC_NUM 별로 1명의 이름만 유일하게 만들어놓았기 때문에 MAX(Name)을 뽑으면 각 OCC_NUM과 직업에 해당하는 1명의 이름이 출력됨)
    FOR Occupation(열로 만들 값이 모인 컬럼) IN ('Doctor' AS Doctor, 'Professor' AS Professor,'Singer' AS Singer,'Actor' AS Actor))

-> Occupation 안의 값(Doctor,Professor,Singer,Actor)을 열로 만듦 

  

 

 

SELECT Doctor,Professor,Singer,Actor
FROM
    (SELECT Name,
           Occupation,
           ROW_NUMBER() OVER (PARTITION BY Occupation ORDER BY Name) AS OCC_NUM
    FROM OCCUPATIONS)
PIVOT
    (MAX(Name)
    FOR Occupation IN ('Doctor' AS Doctor, 'Professor' AS Professor,'Singer' AS Singer,'Actor' AS Actor));

정답 출력에 OCC_NUM은 필요 없으므로  해당 하는 것만 뽑아오면 되는데 위 쿼리처럼 OCC_NUM 순으로 정렬을 해주지 않으면 우리가 원하는 값처럼 NULL을 맨 아래로 출력되게 할 수가 없다

 

SELECT Doctor,Professor,Singer,Actor
FROM
    (SELECT Name,
           Occupation,
           ROW_NUMBER() OVER (PARTITION BY Occupation ORDER BY Name) AS OCC_NUM
    FROM OCCUPATIONS)
PIVOT
    (MAX(Name)
    FOR Occupation IN ('Doctor' AS Doctor, 'Professor' AS Professor,'Singer' AS Singer,'Actor' AS Actor))
ORDER BY OCC_NUM ;

 

그러므로 정렬을 해주고 원하는 컬럼만 가져주면 된다

 

'Database > Oracle' 카테고리의 다른 글

[DataBase] Oracle DBMS Synonym (Public, Private)개념과 실습  (0) 2023.02.21