[SQL] 첫 주문 사례 찾기, 토스 코테 문제

Gi Woon Lee·2025년 4월 22일

SQL

목록 보기
32/33

2025-04-21 토스 코테를 봤다. 상황별 고객을 분류하고, 분류에 따른 집계값을 구하는 문제가 많이 나왔다. 또한 AARRR 각 단계를 분석하는 SQL문제도 많이 나왔다. 탈탈 털렸다.
다음날인 오늘, LEETCODE를 푸는데 비슷한 문제가 나와서 정리하고자 한다.

문제는 고객DB에서 첫 주문 이벤트를 관찰하고, 해당 이벤트에서 당일 배송 확률을 구하는 문제였다.

https://leetcode.com/problems/immediate-food-delivery-ii/

첫 시도.. 아마 이래서 어제 코테에서도 힘들었던게 아닐까 ㅠ
join을 적극 활용하는게 중요한것 같다. CTE+JOIN -> 가장 강력크

첫 쿼리

# Write your MySQL query statement below
-- 1. find first orders 
with t1 as 
(select 
    customer_id, min(order_date) first_order_date, customer_pref_delivery_date,
    case when min(order_date) = customer_pref_delivery_date then 'immediate'
    else 'delayed' end as immediate
from
    Delivery
where 
    order_date <= customer_pref_delivery_date
group by
    customer_id
)
-- 2. find the percentage orders
select 
    round((sum(if(immediate = 'immediate',1,0))/count(immediate) * 100),2) immediate_percentage
from 
    t1

QUESTIONS
1. group by 는 column1 로 하고 select에는 column1 말고 다른 column과 집계값을 조회해도 되는겨?
안된다!!! group by 를 column1로 했으면 집계 없이 조회할 수 있는 칼럼은 column1 뿐.
그래서 정답 쿼리의 CTE에서 우선 customer_id 를 호출한 뒤 JOIN할 때 AND를 통해 customer_id와 날짜가 동일한 조합으로 JOIN한거임.

정답 쿼리

-- 1. find first orders 
WITH first_order_date AS(
    SELECT 
        customer_id, min(order_date) as first_order_date
    FROM 
        delivery
    GROUP BY
        customer_id
)
-- 2. find the percentage orders
SELECT 
    ROUND(sum(d.customer_pref_delivery_date = fod.first_order_date) / count(delivery_id) * 100, 2) as immediate_percentage 
FROM 
    Delivery d JOIN first_order_date fod
    ON d.customer_id = fod.customer_id AND d.order_date = fod.first_order_date

TIL

  • GROUP BY 대상만 SELECT 할 수 있다!!! (다른 칼럼은 집계 후 SELECT 가능)
  • SUM(조건) 의 경우 해당 조건을 충족하는 사건의 수를 집계한다.
    - 조건이 참: 1, 조건이 거짓: 0
  • COUNT(조건) 의 경우 NULL이 아닌 값의 개수를 셈. 따라서 조건 자체가 NULL이 아니라 0이 나올 경우 그냥 COUNT 한다. 한마디로 그냥 행 전부를 세는거임. 쓸데가 없다. 버려.
  • SUM(IF(조건 1, 0)) 👈 이 짓 안하고 그냥 SUM(조건) 사용하면 된다!!

0개의 댓글