Skip to content

Commit 465cd51

Browse files
committed
Update readme.md
1 parent cf7a246 commit 465cd51

File tree

1 file changed

+192
-0
lines changed
  • LeetCode SQL 50 Solution/1075. Project Employees I

1 file changed

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

0 commit comments

Comments
 (0)