19

I have a simple table with a unit_id oid, time timestamp, diag bytea. The primary key is a combination of both time and unit_id.

The idea behind this query is to get the latest row (largest timestamp) for each unique unit_id. However the rows for each unit_id with the latest time are not always returned.

I really want to group by just the unit_id, but postgres makes me use diag also, since I am selecting that.

SELECT DISTINCT ON(unit_id) max(time) as time, diag, unit_id 
FROM diagnostics.unit_diag_history  
GROUP BY unit_id, diag

2 Answers 2

32

Any time you start thinking that you want a localized GROUP BY you should start thinking about window functions instead.

I think you're after something like this:

select unit_id, time, diag
from (
    select unit_id, time, diag,
           rank() over (partition by unit_id order by time desc) as rank
    from diagnostics.unit_diag_history
) as dt
where rank = 1

You might want to add something to the ORDER BY to consistently break ties as well but that wouldn't alter the overall technique.

Sign up to request clarification or add additional context in comments.

2 Comments

Can we do this without using sub select ?
@metdos: I can't think of anything off the top of my head but there might be a way. What's wrong with derived tables?
28

You can join the grouped select with the original table:

SELECT d.time, d.diag, d.unit_id
FROM(
    SELECT unit_id, max(time) as max_time
    FROM diagnostics.unit_diag_history
    GROUP BY unit_id
) s JOIN diagnostics.unit_diag_history d
ON s.unit_id = d.unit_id AND s.max_time = d.time

2 Comments

This is the only answer I have found in several days of Googling that helped me in any way (coming from MySQL).
Very old comment but still very helpful :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.