1

I have a table that looks similar to this:

credit
+---------+----------------+-------------+--------------+-------------------------+
| id (PK) | person_id (FK) | transaction | total credit |        date_time        |
+---------+----------------+-------------+--------------+-------------------------+
|     345 |              1 |       -1.00 |        34.50 | 2018-08-29 12:00:00.000 |
|     897 |              1 |        5.45 |        39.95 | 2018-08-29 12:34:00.000 |
|     378 |              2 |        0.01 |         0.01 | 2018-08-29 08:00:00.000 |
|     789 |              2 |       20.00 |        20.01 | 2018-08-29 09:00:00.000 |
+---------+----------------+-------------+--------------+-------------------------+

How would I write a query in Postgres to return only the most recent (by date_time DESC) row grouped by each unique person_id in the table, like this?

+---------+----------------+-------------+--------------+-------------------------+
| id (PK) | person_id (FK) | transaction | total credit |        date_time        |
+---------+----------------+-------------+--------------+-------------------------+
|     897 |              1 |        5.45 |        39.95 | 2018-08-29 12:34:00.000 |
|     789 |              2 |       20.00 |        20.01 | 2018-08-29 09:00:00.000 |
+---------+----------------+-------------+--------------+-------------------------+
1

2 Answers 2

2

Use distinct on:

select distinct on (person_id) t.*
from t
order by person_id, date_time desc
Sign up to request clarification or add additional context in comments.

Comments

2

You can try this. use ROW_NUMBER with window function to make row number split by person_id and order by date_time in subquery then get row number is 1

CREATE TABLE credit(
   id int,
   person_id int,
   transaction float,
   "total credit" float,
   date_time timestamp
);

INSERT INTO credit values (345,1 ,-1.00,34.50, '2018-08-29 12:00:00.000');
INSERT INTO credit values (897,1 ,5.45 ,39.95, '2018-08-29 12:34:00.000');
INSERT INTO credit values (378,2 ,0.01 ,0.01 , '2018-08-29 08:00:00.000');
INSERT INTO credit values (789,2 ,20.00,20.01, '2018-08-29 09:00:00.000');

Query 1:

SELECT * FROM (
    SELECT *,ROW_NUMBER() OVER (PARTITION BY person_id  ORDER BY date_time DESC) rn
    FROM credit
) t1
where rn = 1

Results:

|  id | person_id | transaction | total credit |            date_time | rn |
|-----|-----------|-------------|--------------|----------------------|----|
| 897 |         1 |        5.45 |        39.95 | 2018-08-29T12:34:00Z |  1 |
| 789 |         2 |          20 |        20.01 | 2018-08-29T09:00:00Z |  1 |

2 Comments

Thanks very much for the detailed example!
@ty2k No problem glad to help

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.