Measure Daily Late-Order Rates by Delivery Zone
Company: DoorDash
Role: Data Scientist
Category: Data Manipulation (SQL/Python)
Difficulty: medium
Interview Round: Technical Screen
The original interview report identified a late-order SQL exercise but did not preserve its exact schema. The following is a self-contained practice reconstruction of that topic.
You have a PostgreSQL table:
```text
orders
------
order_id BIGINT PRIMARY KEY
created_at TIMESTAMPTZ NOT NULL
promised_delivery_at TIMESTAMPTZ NOT NULL
delivered_at TIMESTAMPTZ NULL
status TEXT NOT NULL -- 'completed', 'cancelled', or 'failed'
delivery_zone TEXT NOT NULL -- non-empty delivery market zone
```
Write one PostgreSQL query that produces one row for every UTC calendar date and delivery zone that has at least one eligible order. An eligible order has `status = 'completed'` and a non-null `delivered_at`. Exclude completed rows whose `delivered_at` is null; exclude all cancelled and failed rows. The three grouping/comparison fields `created_at`, `promised_delivery_at`, and `delivery_zone` are guaranteed non-null, and `delivery_zone` is guaranteed non-empty, so no additional null or unknown-zone bucket is needed.
Return these columns:
- `order_date`: the UTC calendar date obtained from the instant in `created_at`, regardless of the timezone offset originally used to write that value
- `delivery_zone`
- `completed_orders`: number of eligible orders in the group
- `late_orders`: number of eligible orders where `delivered_at > promised_delivery_at`
- `late_order_rate`: `late_orders / completed_orders` as a decimal between 0 and 1
- `previous_date_late_order_rate`: the late-order rate for the preceding available `order_date` in the same zone, or `NULL` for the zone's first date
- `late_order_rate_change`: current rate minus `previous_date_late_order_rate`, or `NULL` when there is no previous rate
An order delivered exactly at its promised time is on time. Preserve full numeric precision; do not format the rates as strings or percentages. Order the final result by `order_date` ascending and `delivery_zone` ascending.
Overview: Write a PostgreSQL query for a clearly specified delivery dataset and report daily late-order rates by delivery zone. The practice prompt tests eligibility filtering, timestamp semantics, grouping, precision, and deterministic output requirements.
You have a PostgreSQL table named `orders`. Write one query that returns one row for every UTC calendar date and delivery zone with at least one eligible order. An eligible order has `status = 'completed'` and a non-null `delivered_at`; exclude cancelled and failed orders and completed orders whose `delivered_at` is null.
Return `order_date`, the UTC calendar date derived from `created_at`; `delivery_zone`; `completed_orders`; `late_orders`, where an order is late only when `delivered_at > promised_delivery_at`; `late_order_rate`, calculated as `late_orders / completed_orders`; `previous_date_late_order_rate`, the rate from the preceding available `order_date` in the same zone; and `late_order_rate_change`, the current rate minus that preceding available rate. The two comparison columns must be null for a zone's first available date. An order delivered exactly at its promised time is on time. Preserve full numeric precision rather than formatting rates as strings or percentages. Order the result by `order_date` ascending and `delivery_zone` ascending.
Tables
orders(order_id BIGINT, created_at TIMESTAMPTZ, promised_delivery_at TIMESTAMPTZ, delivered_at TIMESTAMPTZ, status TEXT, delivery_zone TEXT)
Hints
- Convert `created_at` to UTC before taking its calendar date.
- Aggregate eligible orders first, calculate each rate in a second step, then use `LAG` within each delivery zone.
Community answers
Answer by anurag.maji.93
---calendar date x delivery zone: at least one eligible order
Select
cast(created_at as date) as order_date,
delivery_zone,
count (distinct order_id) filter (where delivered_at is not NULL) as completed_orders,
count (distinct order_id) filter (where delivered_at is not NULL and delivered_at > promised_delivery_at) as late_orders,
100*count (distinct order_id) filter (where delivered_at is not NULL and delivered_at > promised_delivery_at)/ count (distinct order_id) filter (where delivered_at is not NULL) as late_order_rate
FROM
orders