Here’s a real-world example that involves using a Common Table Expression (CTE) for ranking records. Let’s consider a scenario where we have two tables:
- Orders Table (Table1): This table stores customer orders.
- OrderHistory Table (Table2): This table stores the history of changes to those orders.
We want to join the latest update for each order (from the OrderHistory table) with the corresponding customer order (from the Orders table).
Schema of the Tables
Orders (Table1):
| id | customer_id | order_date | value |
|---|---|---|---|
| 101 | 1 | 2025-01-01 | 500 |
| 102 | 2 | 2025-01-02 | 300 |
| 103 | 3 | 2025-01-03 | 700 |
OrderHistory (Table2):
| id | order_id | update_date | status |
|---|---|---|---|
| 1 | 101 | 2025-01-01 | Shipped |
| 2 | 101 | 2025-01-02 | Delivered |
| 3 | 102 | 2025-01-02 | Shipped |
| 4 | 103 | 2025-01-04 | Pending |
| 5 | 103 | 2025-01-05 | Shipped |
Goal
We want to:
- Retrieve all orders.
- Show the latest status of each order, based on the most recent update from the
OrderHistorytable.
We can achieve this using a CTE with ROW_NUMBER() to rank the updates for each order by the most recent update_date and then join this with the Orders table.
আমরা এখানে OrderHistory থেকে সবচেয়ে আপডেট স্টাটাস জানবো।
SQL Query with CTE
WITH RankedOrderHistory AS (
SELECT
id,
order_id,
status,
ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY update_date DESC) AS rn
FROM OrderHistory
)
SELECT
o.id,
o.customer_id,
o.order_date,
o.value,
roh.status
FROM
Orders o
LEFT JOIN
RankedOrderHistory roh
ON
o.id = roh.order_id AND roh.rn = 1;Explanation:
- CTE (RankedOrderHistory): This CTE ranks the order history for each
order_idby theupdate_datein descending order. This way, the most recent status gets the row number1. - Main Query: Joins the
Orderstable with the CTE (RankedOrderHistory) to get the latest status (rn = 1) for each order.
Resulting Output
| id | customer_id | order_date | value | status |
|---|---|---|---|---|
| 101 | 1 | 2025-01-01 | 500 | Delivered |
| 102 | 2 | 2025-01-02 | 300 | Shipped |
| 103 | 3 | 2025-01-03 | 700 | Shipped |
Explanation of Output:
- For Order 101, the latest update is “Delivered” (most recent
update_dateof2025-01-02). - For Order 102, the latest update is “Shipped” (most recent
update_dateof2025-01-02). - For Order 103, the latest update is “Shipped” (most recent
update_dateof2025-01-05).
The use of CTE and ROW_NUMBER() ensures that only the most recent status per order is selected.