📝 262. Trips and Users
🔹 여행 및 사용자
취소율은 금지되지 않은 사용자에 대한 취소된(클라이언트 또는 드라이버별) 요청 수를 해당 날짜에 금지되지 않은 사용자에 대한 총 요청 수로 나누어 계산합니다.
"2013-10-01"부터 "2013-10-03" 사이에 매일 금지되지 않은 사용자(클라이언트와 드라이버 모두 금지되지 않아야 함)에 대한 요청 취소 비율을 찾는 솔루션을 작성하세요. 취소율은 소수점 이하 2자리로 반올림됩니다.
어떤 순서로든 결과 테이블을 반환합니다.
📝 문제 설명
- 금지되지 않은 사용자만을 대상으로 취소율을 계산해야 하며,
- 요청 날짜가 2013-10-01 ~ 2013-10-03 사이여야 합니다.
- 취소 상태는 status 컬럼이 'cancelled_by_client' 또는 'cancelled_by_driver'인 경우입니다.
- 취소율은 소수점 둘째 자리까지 반올림해야 합니다.
📊 테이블 구조
Trips 테이블
Column Name | Type |
id | int |
client_id | int |
driver_id | int |
city_id | int |
status | enum |
request_at | varchar |
- status 컬럼의 ENUM은 ('completed', 'cancelled_by_driver', 'cancelled_by_client')입니다.
Users 테이블
Column Name | Type |
users_id | int |
banned | enum |
role | enum |
- banned 컬럼의 ENUM은 ('Yes', 'No')입니다.
- role 컬럼의 ENUM은 ('client', 'driver', 'partner')입니다.
💡 SQL 문제 해결 방법
- 금지되지 않은 사용자를 기준으로 JOIN 조건 설정
- request_at이 지정된 날짜 범위에 해당하는 요청만 필터링
- status가 'cancelled_by_client' 또는 'cancelled_by_driver'인 경우를 집계
- 전체 요청 수 대비 취소 요청 수의 비율 계산
- ROUND() 함수를 통해 소수점 둘째 자리 반올림
- 날짜별로 GROUP BY 수행하여 집계
728x90
🖥️ SQL 풀이
WITH select_trips AS (
SELECT status
, request_at
FROM Trips a
JOIN Users b
ON a.client_id = b.users_id
JOIN Users c
ON a.driver_id = c.users_id
WHERE b.banned != 'Yes'
AND c.banned != 'Yes'
AND a.request_at BETWEEN '2013-10-01' AND '2013-10-03'
)
SELECT request_at AS Day
, ROUND(COUNT(CASE WHEN status LIKE 'cancelled_%' THEN 1 END) * 1.0 / COUNT(*), 2) AS 'Cancellation Rate'
FROM select_trips
GROUP BY request_at
ORDER BY Day;
🔍 쿼리 분석
- WITH select_trips: 서브쿼리를 사용해 필터링된 유효한 여행 요청만 추출
- JOIN Users: 클라이언트와 드라이버가 모두 금지되지 않은 사용자인지 확인
- status LIKE 'cancelled_%': 취소된 요청만 카운트
- ROUND(..., 2): 취소율을 소수점 둘째 자리까지 반올림
- GROUP BY request_at: 날짜별로 취소율 집계
📌 실행 예제
📊 입력 데이터
Trips 테이블
id | client_id | driver_id | city_id | status | request_at |
1 | 1 | 10 | 1 | completed | 2013-10-01 |
2 | 2 | 11 | 1 | cancelled_by_driver | 2013-10-01 |
3 | 3 | 12 | 6 | completed | 2013-10-01 |
4 | 4 | 13 | 6 | cancelled_by_client | 2013-10-01 |
5 | 1 | 10 | 1 | completed | 2013-10-02 |
6 | 2 | 11 | 6 | completed | 2013-10-02 |
7 | 3 | 12 | 6 | completed | 2013-10-02 |
8 | 2 | 12 | 12 | completed | 2013-10-03 |
9 | 3 | 10 | 12 | completed | 2013-10-03 |
10 | 4 | 13 | 12 | cancelled_by_driver | 2013-10-03 |
Users 테이블
users_id | banned | role |
1 | No | client |
2 | Yes | client |
3 | No | client |
4 | No | client |
10 | No | driver |
11 | No | driver |
12 | No | driver |
13 | No | driver |
쿼리 실행 결과
Day | Cancellation Rate |
2013-10-01 | 0.33 |
2013-10-02 | 0.00 |
2013-10-03 | 0.50 |
- 2013-10-01에는 총 4개의 요청이 있었고 그중 2개가 취소되었습니다. 단 id = 2인 여행 요청은 금지된 클라이언트에 의해 이루어졌으므로 제외합니다.
- 따라서 차단되지 않은 사용자에 의한 요청은 총 3건이며 그중 1건이 취소되어 취소율은 1 / 3 = 0.33입니다.
- 2013-10-02에는 총 3개의 요청이 있었고 그중 id = 6인 여행 요청은 금지된 클라이언트에 의해 이루어졌으므로 제외합니다.
- 따라서 차단되지 않은 사용자에 의한 요청은 총 3건이며 취소된 건이 없습니다.
- 2013-10-03에는 총 3개의 요청이 있었고 그중 1개가 취소되었습니다. 단 id = 8인 여행 요청은 금지된 클라이언트에 의해 이루어졌으므로 제외합니다.
- 따라서 차단되지 않은 사용자에 의한 요청은 총 2건이며 그중 1건이 취소되어 취소율은 1 / 2 = 0.5입니다.
🎯 결론
이 문제는 서브쿼리 (WITH), JOIN, 조건부 COUNT, GROUP BY를 활용한 다소 복합적인 SQL 문제입니다.
특히 필터링 조건이 중요한 문제로, 금지되지 않은 사용자만을 정확히 구분하는 것이 핵심입니다.
👉 실무에서 사용자 조건을 나눠 통계 또는 리포트를 추출할 때, 이처럼 JOIN과 조건 필터링을 적절히 조합해야 한다는 점을 기억해 두면 좋습니다! 😊
더 많은 SQL 문제 풀이를 보고 싶다면 LeetCode SQL 문제 모음을 확인해 보세요! 🚀
728x90
반응형
'LeetCode' 카테고리의 다른 글
[LeetCode] 601. Human Traffic of Stadium (4) | 2025.04.18 |
---|---|
[LeetCode] 1393. Capital Gain/Loss (0) | 2025.04.17 |
[LeetCode] 1158. Market Analysis 1 (0) | 2025.04.16 |
[LeetCode] 608. Tree Node (0) | 2025.04.16 |
[LeetCode] 184. Department Highest Salary (0) | 2025.03.26 |