문제: https://datalemur.com/questions/top-fans-rank
나의 풀이
WITH tb AS (
SELECT artist_name
, song_id
, COUNT(*) AS cnt
FROM artists a
JOIN songs s USING (artist_id)
JOIN global_song_rank g USING (song_id)
WHERE rank <= 10
GROUP BY 1, 2)
SELECT *
FROM (
SELECT artist_name
, DENSE_RANK() OVER (ORDER BY SUM(cnt) DESC) AS artist_rank
FROM tb
GROUP BY 1) sub
WHERE artist_rank <= 5
ORDER BY 2, 1;
일단 이렇게 하면 틀림
하지만 디스커션에서 나와 똑같이 생각하는 사람들을 많이 만날 수 있다 ㅋㅅㅋ
문제에서 랭크가 같을 경우 아티스트 이름 기준 오름차순 정렬하라고 되어 있는데
정답에는 같은 랭크에 대해서 B는 D 앞에 오지만(ASC), A는 E 뒤에 옴 (DESC)
either way doesn't work 그래서 나는 문제가 틀렸다고 생각했는데
정답 코드가 있고 정답처리도 잘 된다..
1. 이 부분 왜 그런지 정리해야하고
2. 코드 더 간결하게 수정하기~
먼저 코드 더 간결하게 나타내는 부분! 나는 카운트랑 덴스 랭크를 따로 적용했는데
덴스 랭크 안에 카운트를 넣어서 한 번에 표현 가능하다!
다시 보니 왜 그룹바이를 song_id까지 해서 SUM()을 해줬는지 모르겠다 ㅋㅋ
그룹바이를 artist_name까지만 하고 바로 COUNT() 하면 간단하게 끝난다!
SELECT artist_name
, DENSE_RANK() OVER (ORDER BY COUNT(song_id) DESC)
FROM artists a
JOIN songs s USING (artist_id)
JOIN global_song_rank g USING (song_id)
WHERE rank <= 10
GROUP BY 1;
요렇게 ㅎㅎ
그럼 이제 덴스 랭크가 5순위까지이면서, 중복 랭크에 대해서는 이름 순으로 정렬을 하면 된다.
WITH tb AS (
SELECT artist_name
, DENSE_RANK() OVER (ORDER BY COUNT(song_id) DESC) AS artist_rank
FROM artists a
JOIN songs s USING (artist_id)
JOIN global_song_rank g USING (song_id)
WHERE rank <= 10
GROUP BY 1)
SELECT *
FROM tb
WHERE artist_rank <= 5;
앞에서 만든 쿼리를 위드문안에 담아주고 이걸 테이블처럼 쓰면서 랭킹 5순위 조건을 주면 된다.
따로 정렬 조건을 주지 않은 지금 쿼리 결과는 랭크가 오름차순으로 되어있고 B가 D 앞에 오면서 E가 A 앞에 오는 정답이랑 일치하는 아웃풋이 나온다.
그러니까 결국 아무 정렬 조건을 주지 않은 것임 쿸스..
문제에서 아티스트 이름 순으로 정렬 부분이 수정 되어야할듯..
아무튼 해결!