Skip to content

Commit f863d4f

Browse files
committed
Update readme.md
1 parent 8ff3e3a commit f863d4f

File tree

1 file changed

+186
-0
lines changed
  • LeetCode SQL 50 Solution/1174. Immediate Food Delivery II

1 file changed

+186
-0
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
2+
3+
# **1174. Immediate Food Delivery II**
4+
5+
## **Problem Statement**
6+
You are given a table `Delivery` that records food deliveries made to customers. Each row represents an order with the date it was placed and the customer’s preferred delivery date.
7+
8+
---
9+
10+
## **Delivery Table**
11+
```
12+
+-------------+-------------+------------+-----------------------------+
13+
| Column Name | Type | Description |
14+
+-------------+-------------+----------------------------------------------+
15+
| delivery_id | int | Unique identifier for the delivery |
16+
| customer_id | int | Identifier for the customer |
17+
| order_date | date | Date when the order was placed |
18+
| customer_pref_delivery_date | date | Customer’s preferred delivery date |
19+
+-------------+-------------+----------------------------------------------+
20+
```
21+
- `delivery_id` is the **primary key**.
22+
- Each customer specifies a preferred delivery date, which can be the same as or after the order date.
23+
24+
---
25+
26+
## **Task:**
27+
Calculate the **percentage** of customers whose **first order** is **immediate** (i.e., the order date is the same as the customer’s preferred delivery date).
28+
- A customer’s **first order** is defined as the order with the **earliest order_date** for that customer.
29+
- The result should be **rounded to 2 decimal places**.
30+
- Return the percentage as `immediate_percentage`.
31+
32+
---
33+
34+
## **Example 1:**
35+
36+
### **Input:**
37+
**Delivery Table**
38+
```
39+
+-------------+-------------+------------+-----------------------------+
40+
| delivery_id | customer_id | order_date | customer_pref_delivery_date |
41+
+-------------+-------------+------------+-----------------------------+
42+
| 1 | 1 | 2019-08-01 | 2019-08-02 |
43+
| 2 | 2 | 2019-08-02 | 2019-08-02 |
44+
| 3 | 1 | 2019-08-11 | 2019-08-12 |
45+
| 4 | 3 | 2019-08-24 | 2019-08-24 |
46+
| 5 | 3 | 2019-08-21 | 2019-08-22 |
47+
| 6 | 2 | 2019-08-11 | 2019-08-13 |
48+
| 7 | 4 | 2019-08-09 | 2019-08-09 |
49+
+-------------+-------------+------------+-----------------------------+
50+
```
51+
52+
### **Output:**
53+
```
54+
+----------------------+
55+
| immediate_percentage |
56+
+----------------------+
57+
| 50.00 |
58+
+----------------------+
59+
```
60+
61+
### **Explanation:**
62+
- **Customer 1:** First order is on **2019-08-01** (preferred: 2019-08-02) → **Scheduled**
63+
- **Customer 2:** First order is on **2019-08-02** (preferred: 2019-08-02) → **Immediate**
64+
- **Customer 3:** First order is on **2019-08-21** (preferred: 2019-08-22) → **Scheduled**
65+
- **Customer 4:** First order is on **2019-08-09** (preferred: 2019-08-09) → **Immediate**
66+
67+
Out of 4 customers, 2 have immediate first orders.
68+
Percentage = (2 / 4) * 100 = **50.00**
69+
70+
---
71+
72+
## **SQL Solutions**
73+
74+
### **1️⃣ Standard MySQL Solution**
75+
```sql
76+
SELECT
77+
ROUND(100 * SUM(CASE
78+
WHEN first_orders.order_date = first_orders.customer_pref_delivery_date THEN 1
79+
ELSE 0
80+
END) / COUNT(*), 2) AS immediate_percentage
81+
FROM (
82+
-- Get the first order (earliest order_date) for each customer
83+
SELECT customer_id, order_date, customer_pref_delivery_date
84+
FROM Delivery
85+
WHERE (customer_id, order_date) IN (
86+
SELECT customer_id, MIN(order_date)
87+
FROM Delivery
88+
GROUP BY customer_id
89+
)
90+
) AS first_orders;
91+
```
92+
93+
#### **Explanation:**
94+
- **Subquery:** Retrieves the first order for each customer by selecting the minimum `order_date`.
95+
- **Outer Query:**
96+
- Uses a `CASE` statement to check if the `order_date` equals `customer_pref_delivery_date` (i.e., immediate order).
97+
- Calculates the percentage of immediate first orders.
98+
- Rounds the result to 2 decimal places.
99+
100+
---
101+
102+
### **2️⃣ Window Function (SQL) Solution**
103+
```sql
104+
WITH RankedOrders AS (
105+
SELECT
106+
customer_id,
107+
order_date,
108+
customer_pref_delivery_date,
109+
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date) AS rn
110+
FROM Delivery
111+
)
112+
SELECT
113+
ROUND(100 * SUM(CASE WHEN order_date = customer_pref_delivery_date THEN 1 ELSE 0 END) / COUNT(*), 2) AS immediate_percentage
114+
FROM RankedOrders
115+
WHERE rn = 1;
116+
```
117+
118+
#### **Explanation:**
119+
- **CTE `RankedOrders`:**
120+
- Uses `ROW_NUMBER()` to rank orders for each customer by `order_date`.
121+
- Filters for the first order of each customer (`rn = 1`).
122+
- **Final SELECT:**
123+
- Computes the percentage of first orders that are immediate.
124+
- Rounds the result to 2 decimal places.
125+
126+
---
127+
128+
## **Pandas Solution (Python)**
129+
```python
130+
import pandas as pd
131+
132+
def immediate_food_delivery_percentage(delivery: pd.DataFrame) -> pd.DataFrame:
133+
# Ensure order_date and customer_pref_delivery_date are in datetime format
134+
delivery['order_date'] = pd.to_datetime(delivery['order_date'])
135+
delivery['customer_pref_delivery_date'] = pd.to_datetime(delivery['customer_pref_delivery_date'])
136+
137+
# Get the first order date for each customer
138+
first_order = delivery.groupby('customer_id')['order_date'].min().reset_index()
139+
first_order = first_order.rename(columns={'order_date': 'first_order_date'})
140+
141+
# Merge to get the corresponding preferred delivery date for the first order
142+
merged = pd.merge(delivery, first_order, on='customer_id', how='inner')
143+
first_orders = merged[merged['order_date'] == merged['first_order_date']]
144+
145+
# Calculate immediate orders
146+
immediate_count = (first_orders['order_date'] == first_orders['customer_pref_delivery_date']).sum()
147+
total_customers = first_orders['customer_id'].nunique()
148+
immediate_percentage = round(100 * immediate_count / total_customers, 2)
149+
150+
return pd.DataFrame({'immediate_percentage': [immediate_percentage]})
151+
152+
# Example usage:
153+
# df = pd.read_csv('delivery.csv')
154+
# print(immediate_food_delivery_percentage(df))
155+
```
156+
157+
#### **Explanation:**
158+
- **Convert Dates:**
159+
- Convert `order_date` and `customer_pref_delivery_date` to datetime for accurate comparison.
160+
- **Determine First Order:**
161+
- Group by `customer_id` to find the minimum `order_date` as the first order.
162+
- Merge with the original DataFrame to obtain details of the first order.
163+
- **Calculate Percentage:**
164+
- Count how many first orders are immediate (where `order_date` equals `customer_pref_delivery_date`).
165+
- Compute the percentage and round to 2 decimal places.
166+
167+
---
168+
169+
## **File Structure**
170+
```
171+
LeetCode1174/
172+
├── problem_statement.md # Contains the problem description and constraints.
173+
├── sql_standard_solution.sql # Contains the Standard MySQL solution.
174+
├── sql_window_solution.sql # Contains the Window Function solution.
175+
├── pandas_solution.py # Contains the Pandas solution.
176+
├── README.md # Overview of the problem and available solutions.
177+
```
178+
179+
---
180+
181+
## **Useful Links**
182+
- [LeetCode Problem 1174](https://leetcode.com/problems/immediate-food-delivery-ii/)
183+
- [SQL GROUP BY Documentation](https://www.w3schools.com/sql/sql_groupby.asp)
184+
- [SQL Window Functions](https://www.w3schools.com/sql/sql_window.asp)
185+
- [Pandas GroupBy Documentation](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html)
186+
- [Pandas Merge Documentation](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.merge.html)

0 commit comments

Comments
 (0)