본문 바로가기
문제풀이/SQL(My sql)

[문제풀이] Leet code - Immediate Food Delivery II

by kime2 2024. 8. 13.
출처

 

문제

고객이 선호하는 배송 날짜가 주문 날짜와 같으면 주문을 즉시라고 하고, 그렇지 않으면 예약이라고 합니다.
고객의 첫 번째 주문은 고객이 주문한 날짜가 가장 빠른 주문입니다.

고객이 정확히 하나의 첫 번째 주문을 가지고 있다는 것이 보장됩니다.
모든 고객의 첫 번째 주문에서 즉시 주문의 백분율을 소수점 이하 2자리로 반올림하는 솔루션을 작성합니다.

문제에 대한 해석

1. 고객이 첫 주문한 경우 : 1번 고객은 1번 주문, 2번고객은 2번주문, 3번고객은 5번주문, 4번고객은 7번 주문

> 총 4명의 고객이 첫 주문의 기록이 있다

2. 첫주문 한 고객중 주문날짜와 배송날짜가 동일한 경우 : 2번고객, 4번고객

3. 따라서 첫 주문중 즉시 배송된 비율은 50%

주의 : delivery_id가 주문 날짜 순서가 아님

 

풀이(MYSQL)

-- 오답
with base  as -- 1. 고객 id별 가장 낮은 주문번호 조회
    (select customer_id, min(delivery_id) as 'first_delivery'
    from Delivery
    group by customer_id
    ),
imm as ( -- 2.해당 주문번호를 가진 고객의 데이터를 조회하고 즉시 주문된 주문건 조회
    select count(*) as 'immediate_cnt'
    from base b join Delivery d
    on b.customer_id = d.customer_id
    and b.first_delivery = d.delivery_id
    where d.order_date = d.customer_pref_delivery_date
)
select (select immediate_cnt from imm)/count(*)*100 as 'immediate_percentage '
from base

 

오답원인 : 고객별 가장 낮은 주문번호를 조회했는데, 주문날짜순으로 주문번호가 메겨진 것이 아니어서

가장 먼저 주문 != 가장 낮은 주문번호

 

-- 정답1.
with base  as
    (select customer_id, min(order_date) as 'first_order'
    from Delivery
    group by customer_id
    ),
imm as (
    select count(*) as 'immediate_cnt'
    from base b join Delivery d
    on b.customer_id = d.customer_id
    and b.first_order = d.order_date
    where d.order_date = d.customer_pref_delivery_date
)
select round((select immediate_cnt from imm)/count(*)*100,2) as 'immediate_percentage'
from base

고객별 최조의 주문을 구할때 주문번호가 아닌 주문날짜로 하면 정답이 된다 

 

-- 정답2.
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) 
  from Delivery
  group by customer_id
);

 select 절에 order_date = customer_pref_delivery_date 를 작성하면

다음돠 같이 True, False 로 조회된다