1

I have to do a sql query and I don't know how to do. I'd like to get the latest rows for each unique duo A/B. I'm working with postgresql.

For instance:
Table: Person

id  A  B  modification_date
1   5  6  2014-04-12
2   6  7  2014-04-13
3   5  6  2014-04-14
4   9  1  2014-04-15
5   6  7  2014-04-16

And I'd like to get:

id  A  B  modification_date
3   5  6  2014-04-14
4   9  1  2014-04-15
5   6  7  2014-04-16

Appreciate your help.

Alex
  • 25
  • 8
  • Why is `5 6 2014-04-12` in the expected result? The "latest" (i.e. "newest" row for 5/6 should be `5 6 2014-04-14`, shouldn't it? –  Mar 14 '14 at 09:11
  • You are right a_horse_with_no_name, i corrected – Alex Mar 14 '14 at 09:41

3 Answers3

3
SELECT DISTINCT ON (a, b)
       *
FROM   person
ORDER  BY a, b, modification_date DESC;

Detailed explanation:
Select first row in each GROUP BY group?

Community
  • 1
  • 1
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
1

SELECT the MAXimum of modification_date for each GROUP of (A, B), then JOIN back to the original row to get the values (necessary to get the id column):

SELECT t1.*
FROM Person t1
JOIN
(
    SELECT MAX(modification_date) max_date, A, B
    FROM Person
    GROUP BY A, B
) t2 ON t1.A = t2.A AND t1.B = t2.B AND t1.modification_date = t2.max_date

More simply, if you don't care which id you get back, and you only want one row even if modification_date is duplicated, you can just select the MINimum value of id and be done with it:

SELECT MIN(id) id, A, B, MAX(modification_date) modification_date
FROM Person
GROUP BY A, B
lc.
  • 113,939
  • 20
  • 158
  • 187
0
SELECT id, a, b, modification_date
FROM person p
WHERE NOT EXISTS (
    SELECT *
    FROM person nx
    WHERE nxa = pa AND nx.b = p.b
    AND (nx.modification_date > p.modification_date
         OR nx.modification_date = p.modification_date AND nx.id > p.id)
    );
joop
  • 4,330
  • 1
  • 15
  • 26