문제 2. 결제 없이 주문한 사용자 찾기 (난이도 중)
- 테이블 설명 :
payments 테이블은 사용자의 결제 정보를 포함합니다. 테이블 구조는 다음과 같으며, ID, USER_ID, AMOUNT, PAY_DATE, 그리고 PAYMENT_TYPE은 각각 결제 ID, 사용자 ID, 결제 금액, 결제 날짜, 결제 유형(카드, 현금 등)을 나타냅니다.
- 컬럼명 타입 설명
ID | INT | 결제 ID (PK) |
USER_ID | VARCHAR | 사용자 ID |
AMOUNT | INT | 결제 금액 |
PAY_DATE | DATETIME | 결제 날짜 |
PAYMENT_TYPE | INT | 결제 유형 (0: 현금, 1:카드) |
orders 테이블은 사용자의 상품 배송 정보를 포함합니다. 테이블 구조는 다음과 같으며, ID, USER_ID, ORDER_DATE, 그리고 ITEM은 각각 주문 ID, 사용자 ID, 주문 날짜, 주문한 상품명을 나타냅니다. 해당 테이블의 USER_ID 는 payments 테이블의 USER_ID랑 동일합니다.
- 분석해야 할 내용은 다음과 같습니다 :
최근 특정 사용자들이 결제를 하지 않고 상품을 주문하거나, 결제를 하지 않은 시점에 이미 상품을 주문하는 버그가 발견되었습니다.
해당 버그를 악용한 사용자를 파악하기 위해 SQL 문을 작성해주세요. 다음 조건에 해당되는 사용자 수를 출력해주세요 :
- 결제를 하지 않고 상품을 주문한 사용자
- 첫 번째 결제일보다 이전에 상품을 주문한 사용자
- 출력 값 예시
다음과 같이 결과 출력이 되어야 합니다. (해당 테이블은 예시이며, 실제 정답과 다를 수 있습니다.)
cnt |
2 |
💡 문제 풀이
`내 풀이`
-- 결제를 하지 않고 상품을 주문한 사용자 -> orders에 있는데 payments에 없는애 -> LEFT JOIN해서 null값인 애만 남기
-- 첫 번째 결제일보다 이전에 상품을 주문한 사용자 -> 고객의 첫번째 order_date가 첫번째 pay_date보다 빠른 경우
-- 결제하지 않고 주문한 사용자
with t1 as(
SELECT distinct user_id
FROM orders o
LEFT JOIN payments p USING(user_id)
WHERE p.user_id IS NULL
),
-- 첫번째 결제일보다 이전에 상품을 주문한 사용자
t2 as(
SELECT user_id
FROM payments p
LEFT JOIN orders o USING(user_id)
GROUP BY user_id
HAVING min(order_date) < min(pay_date)
),
-- 두 사용자 합산
uni as(
SELECT *
FROM t1
UNION ALL
SELECT *
FROM t2
)
-- 중복 제거한 사용자 숫자 카운트
SELECT count(distinct user_id) AS cnt
FROM uni;
`오답노트`
- 처음에 다 풀어놓고 2033으로 오답이 나왔는데 이유가 left join 하면서 orders이랑 payments 순서를 잘못해서였다. 왜자꾸 이런 사소하고 중대한 실수를 하는 건지.. 정신 차리자 정신
`출력 결과`