If your DBMS supports WITH
clauses and window functions, you can use
WITH a AS (
SELECT o.Order,
o.Orderdate,
s.Statuschange,
s.Changedate,
s.Changetype,
Row_number() OVER(partition by o.Order
order by s.statuschange desc, s.changedate desc)
as no
FROM Orders o
JOIN Statuschange s ON o.Order = s.Order
WHERE s.Changetype = 'Shipping'
)
SELECT Order,
Orderdate,
Statuschange,
Changedate,
Changetype
FROM a
WHERE no = 1
Row_number() over(...)
does the main work here: it first partitions the result set into partitions, where all records having the same value of o.Order
get to the same partition. Then, within each partition, it numbers the records starting from 1, ordered first by s.statuschange
descending, and those with the same s.statuschange
value by s.changedate
descending.
Finally, the outer select just excludes all the records not having number 1
via is WHERE
clause, which effectively returns the records with the maximum changedate
of those having the maximum statuschange
for each Order
.
This assumes the following - which is not absolutely clear from your question:
- You want to have the entry with the maximum
changedate
of those having the maximumstatuschange
per order. (Reading your question literally, you request the entry with the maximumchangedate
of those having the maximumstatuschange
across all orders. If that would really be your request, you should omit thepartition by o.Order
.) - You want to see the
Changetype
in the result (which you did not state, your expected result does not contain this column).