HackerRank - Occupations (Pivot)
다음은 정답 쿼리중 하나이다....
하지만 고려하지 못하는 부분이 있으니 그부분을 찾아보고 어떻게 고쳐야할지 생각해보자...
with
doct as (
select row_number() over (order by name) as rownumber, name
from occupations where occupation = 'Doctor'
),
prof as (
select row_number() over (order by name) as rownumber, name
from occupations where occupation = 'Professor'
),
sing as (
select row_number() over (order by name) as rownumber, name
from occupations where occupation = 'Singer'
),
acto as (
select row_number() over (order by name) as rownumber, name
from occupations where occupation = 'Actor'
)
select doct.name, prof.name, sing.name, acto.name
from doct, prof, sing, acto
where prof.rownumber(+) = doct.rownumber
and prof.rownumber = sing.rownumber(+)
and prof.rownumber = acto.rownumber(+)
;
위의 경우 의도와 같은 결과가 나오기 위해서는 prof가 가장 인원수가 많다는 사실을 알고있어야 한다. 그래서 쿼리를 다음과 같이 고쳐보았다.
select
min(CASE WHEN Occupation = 'Doctor' THEN Name END) AS Doctor,
min(CASE WHEN Occupation = 'Professor' THEN Name END) AS Professor,
min(CASE WHEN Occupation = 'Singer' THEN Name END) AS Singer,
min(CASE WHEN Occupation = 'Actor' THEN Name END) AS Actor
from(
select occupation, name, rank() over(partition by occupation order by name) as rn
from occupations
)
group by rn;
이에 위 와 같은 쿼리를짰으나 (순위를 메겨 순위별로 행을 나누려했음)
Aamina Ashley Christeen Eve
NULL Naomi NULL NULL
Julia Belvet Jane Jennifer
NULL Maria Kristeen Samantha
NULL Meera NULL NULL
Priya Britney Jenny Ketty
NULL Priyanka NULL NULL
가 나왔고 NULL을 모두 밑으로 내리고싶었다. (아직도 왜 위의 쿼리가 위와같은 결과를 나타내는지 이해는 안됨)
그래서 pivot 문을 사용했다.
select Doctor,Professor,Singer,Actor from
(select Name,Occupation, row_number() over(partition by Occupation order by Name) rnk
from OCCUPATIONS)
pivot
(
max(Name)
for Occupation in ('Doctor' Doctor,'Professor' Professor,'Singer' Singer,'Actor' Actor)
) order by rnk;
Oracle에서 PIVOT 문은 테이블의 행을 열로 변환하여 집계 함수를 적용할 때 사용하는 SQL 구문입니다. PIVOT을 사용하면 테이블의 데이터를 다른 형식으로 재구성하고 요약하는 작업을 편리하게 수행할 수 있습니다. 주로 교차표(Cross-Tab) 작성이나 요약 보고서 작성에 사용됩니다.
PIVOT 문의 기본 구문은 다음과 같습니다:
SELECT *
FROM (원본 쿼리) -- 원본 쿼리는 피벗할 데이터를 가져오는 서브쿼리입니다.
PIVOT
(
집계_함수(집계할_열)
FOR 피벗_열 IN (피벗값1, 피벗값2, ..., 피벗값n)
);
- 집계_함수: 피벗된 결과를 집계하는데 사용할 집계 함수를 지정합니다. 예를 들어, SUM, COUNT, AVG, MAX, MIN 등의 함수를 사용할 수 있습니다.
- 집계할_열: 집계 함수를 적용할 열을 지정합니다.
- 피벗_열: 행을 열로 변환할 기준 열을 지정합니다. 이 열의 고유한 값을 열로 변환합니다.
- 피벗값1, 피벗값2, ..., 피벗값n: 피벗 열의 가능한 고유한 값들을 나열합니다. 각 값은 결과의 열로 변환됩니다.
다음은 간단한 예제를 통해 PIVOT 문을 설명합니다. 다음은 "sales" 테이블에서 월별 판매 데이터를 피벗하는 쿼리입니다
SELECT *
FROM (
SELECT month, product, amount
FROM sales
)
PIVOT
(
SUM(amount)
FOR product IN ('Product A' AS A, 'Product B' AS B, 'Product C' AS C)
);
이 쿼리는 "sales" 테이블에서 월별 판매 데이터를 가져와서 "product" 열을 열로 변환합니다. 결과는 월별로 "Product A," "Product B," "Product C"의 판매 합계가 표시된 피벗된 테이블입니다.
PIVOT을 사용하면 데이터를 편리하게 피벗할 수 있으며, 교차표를 생성하거나 요약 보고서를 작성하는 데 유용합니다.
Pivot을 통해 2차원 데이터를 전치할 수 있습니다.