본문 바로가기

[LeetCode] 262. Trips and Users

by qwee0328 2025. 4. 18.

📝 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 문제 해결 방법

  1. 금지되지 않은 사용자를 기준으로 JOIN 조건 설정
  2. request_at이 지정된 날짜 범위에 해당하는 요청만 필터링
  3. status가 'cancelled_by_client' 또는 'cancelled_by_driver'인 경우를 집계
  4. 전체 요청 수 대비 취소 요청 수의 비율 계산
  5. ROUND() 함수를 통해 소수점 둘째 자리 반올림
  6. 날짜별로 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