본문 바로가기
Programming/SQL

[LeetCode] 1174. Immediate Food Delivery - AVG안에 조건식 넣기

by 수박주스으 2025. 2. 3.

문제 링크 : https://leetcode.com/problems/immediate-food-delivery-ii

 

문제 설명

- 만약 customer_pref_delivery_date = order_date 라면 'immediate'라고 한다. 다를 경우 'scheduled'

- first_order(첫주문)은 고객의 주문 내역 중, 가장 빠른 날짜에 주문한 것을 기준으로 한다.

- 전체 고객의 첫 주문 중에서, immediate인 주문 비율을 구하고, 반올림하여 소수점 2번째 자리까지 표현.

 

솔루션

WITH First_order AS (
    SELECT customer_id, MIN(order_date) AS first_order
    FROM Delivery
    GROUP BY customer_id
)
SELECT ROUND(COUNT(DISTINCT CASE WHEN order_date = customer_pref_delivery_date THEN customer_id END) / COUNT(DISTINCT customer_id) * 100, 2) AS immediate_percentage
FROM Delivery
WHERE (customer_id, order_date) IN (SELECT * FROM First_order)

- 먼저 customer_id별로 첫 주문한 날짜를 구한다.

- 위에서 구한 (customer_id, 첫주문날짜) 쌍을 필터링 조건으로 넣어 Delivery테이블에서 조회한다.

- immediate인 주문 비율을 구한다.

 

일단 답은 맞았지만... 실행시간이 1460ms으로 생각보다 길어서 놀랐다.

그래서 WITH을 없애고 WHERE절에 서브쿼리로 넣어봤는데 838ms으로 단축됐다. WITH절이 생각보다 시간을 많이 잡아먹는 구나 싶었다...

2024.02.04

다음날 똑같은 코드로 다시 실행했더니 반대의 결과가 나왔다. 수정한 코드의 실행시간이 더 길게 나온 것이었다...

WITH문의 사용 여부가 크게 영향을 미치는 것 같지는 않고,

실행했을 때의 인터넷 환경이나 리트코드 사이트 자체가 원인인 듯 싶다.

WITH문을 사용한 성능개선과 관련해서 유용한 자료를 참고자료로 걸어둔다.

 

https://schatz37.tistory.com/46

 

[SQL] with 절을 효율적으로 사용하기

요즘 회사에서 '어떻게 하면 보다 효율적인 sql을 작성할 수 있을까?' 라는 부분에 굉장히 많이 고민하고 있는데요. 이번 포스팅에서는 공부가 필요하다고 생각되는 with절에 대해서 포스팅하려

schatz37.tistory.com

 

<수정한 코드>

SELECT ROUND(COUNT(DISTINCT CASE WHEN order_date = customer_pref_delivery_date THEN customer_id END) / COUNT(DISTINCT customer_id) * 100, 2) AS immediate_percentage
FROM Delivery
WHERE (customer_id, order_date) IN (SELECT customer_id, MIN(order_date) AS first_order
                                    FROM Delivery
                                    GROUP BY customer_id)

 

 

그리고 다른 사람 답을 참고하면서 새롭게 알게 된 부분도 있다.

나는 비율을 구할 때

(주문이 immediate인 customer_id 개수) / (전체 customer_id 개수)

로 구했는데, 생각해보면 (전체 행 개수) 대비 (주문이 immediate인 행)의 비율을 구하는 것과 같다.

이것을 AVG함수 안에 조건식을 넣어서 해결할 수 있다는 점! 이었다.

SELECT ROUND(AVG(order_date = customer_pref_delivery_date) * 100, 2) AS immediate_percentage
FROM Delivery
WHERE (customer_id, order_date) IN (SELECT customer_id, MIN(order_date) AS first_order
                                    FROM Delivery
                                    GROUP BY customer_id)

 

관련해서 gpt한테 물어봤더니,

 

정리해보면, AVG(조건식)의 코드에서

1. '조건식'은 Boolean 값으로 처리되어 True일 경우 1, False일 경우 0으로 계산한다.

2. 1과 0의 평균을 구한다. 즉, 1 0 1 0 1 총 5개의 결과값이 있다면 AVG는 3/5=0.6, 즉 60% 비율값을 구하는 것과 같다.

참고로 AVG뿐만 아니라 SUM함수에 대해서도 적용가능하다.