SQL 문제풀이 복습
문제 링크
6/30에 이어 두 번째로 풀게 된 문제.
첫 번째 풀이 때는 CTE도 2개를 만들고
조건을 꽤나 복잡하게 썼었는데,
오늘은 생각보다 훨씬 더 간단하게 풀렸다.
그냥 조인의 조건 + 문제에서 요구하는 조건만 잘 넣으면
CTE를 쓸 것도 없이 한방에 해결할 수 있었음.
Cancellation Rate를 구할 때 분자 자리에 들어가는
Count + Case when 조합만 신경쓸 것. (end 처리)
SELECT t.request_at AS "Day",
Round(Count(CASE
WHEN t.status LIKE 'cancelled%' THEN t.id
end) / Count(DISTINCT t.id), 2) AS "Cancellation Rate"
FROM trips t
LEFT JOIN users u
ON t.client_id = u.users_id
LEFT JOIN users u2
ON t.driver_id = u2.users_id
WHERE u.banned <> 'YES'
AND u2.banned <> 'YES'
AND request_at BETWEEN '2013-10-01' AND '2013-10-03'
GROUP BY 1;
SELECT player_id,
Min(event_date) AS "first_login"
FROM activity
GROUP BY 1;
문제 링크
7/4에 이어 두 번째로 풀게 된 문제.
처음 풀이 때는 CTE를 만들어서
플레이어별로 가장 빠른 날짜를 구해 놓고
본 쿼리에서 join을 해서 id와 빠른 날짜를 매칭시키는 방식으로 풀었다.
WITH first
AS (SELECT player_id,
Min(event_date) AS first
FROM activity
GROUP BY 1)
SELECT first.player_id,
a.device_id
FROM first
INNER JOIN activity a
ON first.player_id = a.player_id
AND first.first = a.event_date;
오늘은 CTE 없이 서브쿼리로 해결했고,
window 함수 중 rank를 써서 플레이어별로 ranking이 1인,
즉 가장 빠른 event_date에 해당하는 player_id와 device_id만 갖고오도록 했다.
SELECT player_id,
device_id
FROM (SELECT player_id,
device_id,
Rank()
OVER(
partition BY player_id
ORDER BY event_date) AS "ranking"
FROM activity) a
WHERE ranking = '1';
풀이가 겹치는 걸 피하고 싶어서
일부러 첫 번째 풀이와는 다르게 접근해 봤다.
여러 개념을 두루 리마인드하기 위해서라도 이 방법이 좋을 듯.