Собесов

LeetCode SQL — Immediate Food Delivery II: первый заказ как immediate

SQLАналитика first-touchСредняяMiddle

Условие

Таблица Delivery(delivery_id, customer_id, order_date, customer_pref_delivery_date).

«Immediate» — order_date = customer_pref_delivery_date. «Scheduled» — иначе.

Для каждого клиента берём только его первый заказ (по order_date). Найдите долю клиентов, у которых первый заказ — immediate. Округлить до 2 знаков, в процентах (*100).

Решение

Через MIN(order_date) на клиента

WITH firsts AS (
  SELECT customer_id, MIN(order_date) AS first_date
  FROM Delivery
  GROUP BY customer_id
),
joined AS (
  SELECT d.*
  FROM Delivery d
  JOIN firsts f
    ON f.customer_id = d.customer_id
   AND f.first_date  = d.order_date
)
SELECT
  ROUND(
    100.0 * AVG(CASE WHEN order_date = customer_pref_delivery_date THEN 1 ELSE 0 END),
    2
  ) AS immediate_percentage
FROM joined;

Через ROW_NUMBER()

WITH ranked AS (
  SELECT
    customer_id, order_date, customer_pref_delivery_date,
    ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date) AS rn
  FROM Delivery
)
SELECT
  ROUND(
    100.0 * AVG(CASE WHEN order_date = customer_pref_delivery_date THEN 1 ELSE 0 END),
    2
  ) AS immediate_percentage
FROM ranked
WHERE rn = 1;

Подводные камни

  1. Тай-брейк по order_date. Если в один день два заказа от клиента — MIN(order_date) даст обе строки. В задаче гарантировано один заказ в день, но в проде это рискованно — лучше ROW_NUMBER с детерминированным ORDER BY (order_date, delivery_id).
  2. 100.0 *, не 100 *. В MySQL/Postgres целочисленное деление обрежет до 0.
  3. AVG vs SUM/COUNT. Делать AVG(CASE...) короче, но в некоторых СУБД (Oracle, SQL Server) поведение с булевыми отличается. Универсально — SUM(CASE ... THEN 1 ELSE 0 END)::DECIMAL / COUNT(*).

Эталонный ответ

ROW_NUMBER по клиенту с ORDER BY order_date, фильтр rn = 1, доля через AVG(CASE...) × 100, ROUND(..., 2).

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти