There is a table with Order ID, Delivery Date, Delivery Sequence Number, and Record Update Date & Time. When a product is in the warehouse, the default delivery date is set to 1999-12-31, indicating that the product is not ready for delivery. When the product is scheduled for delivery, the record displays the actual delivery date. If the record is modified, a new row is inserted with a new sequence number, along with the updated record’s modification date and time.
The expected output, as mentioned in the output column, is to replace the default date with the most recent actual delivery date (which is not equal to ‘1999-12-31’). For example, for Order 1, when the record shows ‘2019-01-11 13:00 AM’ (indicating the product is in the warehouse), it should be replaced with the actual delivery date ‘2019-01-21’.
Order id | Delivery date | delivery sequence | record update dttm | expected output |
---|---|---|---|---|
1 | ‘2019-01-20’ | 1 | ‘2019-01-10 10:00:00 AM’ | ‘2019-01-20’ |
1 | ‘2019-01-21’ | 2 | ‘2019-01-10 11:00:00 AM’ | ‘2019-01-21’ |
1 | ‘1999-12-31’ | 3 | ‘2019-01-11 13:00:00 AM’ | ‘2019-01-21’ |
1 | ‘1999-12-31’ | 4 | ‘2019-01-12 13:30:00 PM’ | ‘2019-01-21’ |
1 | ‘2019-01-29’ | 5 | ‘2019-01-13 09:00:00 AM’ | ‘2019-01-29’ |
2 | ‘2019-04-30’ | 1 | ‘2019-04-29 09:00:00 AM’ | ‘2019-04-30’ |
2 | ‘2019-03-18’ | 2 | ‘2019-04-30 11:00:00 AM’ | ‘2019-03-18’ |
2 | ‘1999-12-31’ | 3 | ‘2019-04-30 13:00:00 AM’ | ‘2019-03-18’ |
2 | ‘2020-03-31’ | 4 | ‘2019-05-01 13:30:00 PM’ | ‘2020-03-31’ |
2 | ‘1999-12-31’ | 5 | ‘2019-05-13 10:00:00 AM’ | ‘2020-03-31’ |
2 | ‘1999-12-31’ | 6 | ‘2019-05-13 10:00:00 AM’ | ‘2020-03-31’ |
2 | ‘1999-12-31’ | 7 | ‘2019-05-14 10:00:00 AM’ | ‘2020-03-31’ |
3 | ‘2019-01-20’ | 1 | ‘2019-01-20 10:00:00 AM’ | ‘2019-01-20’ |
3 | ‘1999-12-31’ | 2 | ‘2019-01-10 10:00:00 AM’ | ‘2019-01-20’ |
3 | ‘2019-01-22 | 3 | ‘2019-01-10 11:00:00 AM’ | ‘2019-01-22’ |
4
SELECT
OrderID,
DeliveryDate,
DeliverySequence,
RecordUpdateDTTM,
CASE
WHEN DeliveryDate = '1999-12-31' THEN NULL
ELSE DeliveryDate
END AS UpdatedDeliveryDate
INTO #TEMP
FROM Orders
;WITH CTE AS (
SELECT
OrderID,
DeliveryDate,
DeliverySequence,
RecordUpdateDTTM,
UpdatedDeliveryDate AS ExpectedOutput
FROM #TEMP
WHERE DeliverySequence = 1
UNION ALL
SELECT
c.OrderID,
c.DeliveryDate,
c.DeliverySequence,
c.RecordUpdateDTTM,
COALESCE(c.UpdatedDeliveryDate, r.ExpectedOutput) AS ExpectedOutput
FROM #TEMP c
INNER JOIN CTE r
ON c.OrderID = r.OrderID AND c.DeliverySequence = r.DeliverySequence + 1
)
SELECT
OrderID,
DeliveryDate,
DeliverySequence,
RecordUpdateDTTM,
ExpectedOutput
FROM CTE
ORDER BY OrderID, DeliverySequence;
If you want the latest valid delivery date for a group of order_id, you can simply PARTITION BY
order_id and ORDER BY
delivery_sequence and use a MAX()
to get the latest delivery_date for each order_id
Fiddle
SELECT
o.order_id,
o.delivery_date,
o.delivery_sequence,
o.record_update_dttm,
COALESCE(
NULLIF(o.delivery_date, '1999-12-31'),
MAX(CASE WHEN o.delivery_date != '1999-12-31' THEN o.delivery_date END)
OVER (PARTITION BY o.order_id ORDER BY o.delivery_sequence )
) AS expected_output
FROM orders o
ORDER BY o.order_id, o.delivery_sequence;
Output
order_id | delivery_date | delivery_sequence | record_update_dttm | expected_output |
---|---|---|---|---|
1 | 2019-01-20 | 1 | 2019-01-10 10:00:00 | 2019-01-20 |
1 | 2019-01-21 | 2 | 2019-01-10 11:00:00 | 2019-01-21 |
1 | 1999-12-31 | 3 | 2019-01-11 13:00:00 | 2019-01-21 |
1 | 1999-12-31 | 4 | 2019-01-12 13:30:00 | 2019-01-21 |
1 | 2019-01-29 | 5 | 2019-01-13 09:00:00 | 2019-01-29 |
2 | 2019-04-30 | 1 | 2019-04-29 09:00:00 | 2019-04-30 |
2 | 2019-03-18 | 2 | 2019-04-30 11:00:00 | 2019-03-18 |
2 | 1999-12-31 | 3 | 2019-04-30 13:00:00 | 2019-04-30 |
2 | 2020-03-31 | 4 | 2019-05-01 13:30:00 | 2020-03-31 |
2 | 1999-12-31 | 5 | 2019-05-13 10:00:00 | 2020-03-31 |
2 | 1999-12-31 | 6 | 2019-05-13 10:00:00 | 2020-03-31 |
2 | 1999-12-31 | 7 | 2019-05-14 10:00:00 | 2020-03-31 |
3 | 2019-01-20 | 1 | 2019-01-20 10:00:00 | 2019-01-20 |
3 | 1999-12-31 | 2 | 2019-01-10 10:00:00 | 2019-01-20 |
3 | 2019-01-22 | 3 | 2019-01-10 11:00:00 | 2019-01-22 |
You can query the max(delivery_date) for each order id, and then join the result to the original table. For the expected_output column, use a case when delivery_date = ‘1999-12-31’.
select se.order_id,
se.delivery_date,
se.delivery_sequence,
se.record_update_dttm,
case when se.delivery_date = '1999-12-31' then agg.max_delivery_date
else se.delivery_date end expected_output
from se_orders se
inner join
(
select order_id, max(delivery_date) max_delivery_date
from se_orders
group by order_id
) agg
on se.order_id = agg.order_id
order by se.order_id, se.delivery_sequence;