DJ_Stuffy_K
DJ_Stuffy_K

Reputation: 635

postgresql Select all rows which have max value in one column

I'm new to postgresql, I have a table T like this in postgresql:

C1 C2 C3 C4 ID

C1,C2, C4 are int.
C3 is a char C4 is essentially the version number. and can be anything between 1-N.
( For example, after one set of insert events the values in table are updated.) ID is a char.

Question:
For a given value of ID, I want to select all rows that have highest C4 associated with them. For example there could be N versions in the table, I want all results corresponding to the version N.

I tried,

select C1,C2,C3, max(C4) from T where ID = 'something';

but it gives me error.

Please advise.

Upvotes: 4

Views: 11122

Answers (1)

Haleemur Ali
Haleemur Ali

Reputation: 28253

update for postgresql version 13+

the latest version of postgresql introduces limit ... with ties

SELECT id, c1, c2, c3, c4
FROM t
WHERE id = 'something'
ORDER BY c4 DESC
FETCH FIRST 1 ROW WITH TIES

Specifying WITH TIES will return all the rows where c4 equals the largest value in that columns, so a separate CTE with a window function is not required. If there is only 1 row where c4 has its maximum values, then only 1 row will be returned.


original answer (for earlier versions of postgresql):

If there can be multiple rows for the same version number, then use the window function RANK in a cte and select the rows where rank equals 1

SELECT id, c1, c2, c3, c4 
FROM (
    SELECT 
      *
    , RANK() OVER (PARTITION BY id ORDER BY c4 DESC) c4rank
    FROM t
) ranked 
WHERE c4rank = 1
  AND id = 'something'

If you want the most recent version for all ids, just omit the condition id = 'something' from the above statement.

If there can only be 1 row for a given version number then use order by and limit 1

SELECT id, c1, c2, c3, c4
FROM t
WHERE id = 'something'
ORDER BY c4 DESC
LIMIT 1

If you want the most recent version for all ids & there can only be 1 row per (id, version) combination

SELECT DISTINCT ON (id) id, c1, c2, c3, c4
FROM t
WHERE id = 'something'
ORDER BY id, c4 DESC

Upvotes: 14

Related Questions