I have an orders
table that has a primary key id
column, an order_id
column, and a created_date
column:
===================================
ORDERS
===================================
id | order_id | created_date
-----------------------------------
1 | 178 | 2022-11-16 09:25:11
2 | 182 | 2022-11-18 08:44:19
3 | 178 | 2022-11-17 11:16:22
4 | 178 | 2022-11-18 14:55:41
5 | 195 | 2022-11-15 09:11:17
6 | 195 | 2022-11-16 21:22:32
7 | 146 | 2022-11-16 16:55:09
8 | 178 | 2022-11-16 04:39:16
9 | 121 | 2022-11-16 01:20:19
I want to write a query that returns the highest created_date
for a specific order_id
, so I’m trying to use MAX()
. But I would also like to return the id
of that highest created_date
row. In the example above, let’s say that I would like to return the row that fits this criteria for order ID 178:
SELECT MAX(o.created_date),
o.id
FROM orders o
WHERE o.order_id = 178
GROUP BY o.id;
The problem is that when I write the query like this, I get multiple rows returned. I’ve tried removing the GROUP BY
altogether but aside from that, I cannot wrap my head around what I would need to do to this query to show the following information:
4 | 2022-11-18 14:55:41
How can I write a PostgreSQL query to show the row with the highest created_date
value but also show other information for that row?
4
Answers
You will have to use a CTE to calculate which is the latest
order_id
by usingROW_NUMBER()
and the correctORDER BY
. After that, select the entire row using this pseudo-ranker.dbfiddle
If you don’t care about multiple order_id’s having the identic latest date, you can just use
LIMIT
:If different order id’s can appear and you want to get all of them, in Postgres DB’s, you can use
FETCH FIRST 1 ROW WITH TIES
(thanks to a_horse_with_no_name for that hint!):As a more general way, you could also use a window function, for a example
DENSE_RANK
:An easy way to do this is to use
distinct on
, and get the max value byorder by desc
instead ofmax
. Something like this:Use
CASE
statement with sub-selects if you don’t want to use CTE: