Reputation: 5206
How to get all rows with the maximum date from a query in PostgreSQL?
For example, if I got the following rows:
1, 1, '2014-05-27'
2, 2, '2014-05-26'
3, 3, '2014-05-26'
4, 4, '2014-05-25'
5, 5, '2014-05-27'
I need to get this result:
1, 1, '2014-05-27'
5, 5, '2014-05-27'
Only the ones with the maximum date - but all of those. This gets it done by repeating the query in a subquery:
SELECT *
FROM table
WHERE field_1 = '1'
AND date_1 = (SELECT MAX(date_1) FROM table WHERE field_1 = '1');
Is there a simpler / faster way (without repeating the query)?
Maybe with the HAVING
clause?
Upvotes: 1
Views: 1013
Reputation: 656714
To get only rows for the latest date in the query use the window function rank()
.
You need a subquery (or CTE), because window functions are applied after WHERE
and HAVING
.
The HAVING
clause is not applicable without because you are not aggregating rows.
SELECT *
FROM (
SELECT *, rank() OVER (ORDER BY date_1 DESC) AS rnk
FROM tbl
WHERE field_1 = '1'
) sub
WHERE rnk = 1;
Your original query may be even faster for simple cases. Indexes on field_1
and date_1
are the key to good performance. The optimum for either query would be a multicolumn index:
CREATE INDEX foo ON tbl (field_1, date_1 DESC);
If date_1 can be NULL you may want to use NULLS LAST in index and query. See:
Upvotes: 0
Reputation: 4251
I think this will work:
select *
from table table1 join (
select max(date_1) theMaxDate from table) table2
on table1. date_1= table2. theMaxDate
Here we are selecting the MaxDate from the table (aliased as table2). This maxDate will be referenced as table2.theMaxDate.
Then we join with the the table (which I referenced as table1 but that's not required).
We join where the date in table1 equals the max date from table2.
I don't think you can do this with a having.
Does this work for you?
Upvotes: 1
Reputation: 916
This might work ;)
SELECT *
FROM table
WHERE field_1 = '1'
ORDER BY date_1 DESC
LIMIT 1 OFFSET 0
Upvotes: 0