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