Postgresql extrahiert die letzte Zeile für jede ID


77

Angenommen, ich habe die nächsten Daten

  id    date          another_info
  1     2014-02-01         kjkj
  1     2014-03-11         ajskj
  1     2014-05-13         kgfd
  2     2014-02-01         SADA
  3     2014-02-01         sfdg
  3     2014-06-12         fdsA

Ich möchte für jede ID die letzten Informationen extrahieren:

  id    date          another_info
  1     2014-05-13         kgfd
  2     2014-02-01         SADA
  3     2014-06-12         fdsA

Wie könnte ich das schaffen?

Antworten:


150

Am effizientesten ist es, den distinct onOperator von Postgres zu verwenden

select distinct on (id) id, date, another_info
from the_table
order by id, date desc;

Wenn Sie eine Lösung suchen, die datenbankübergreifend funktioniert (aber weniger effizient ist), können Sie eine Fensterfunktion verwenden:

select id, date, another_info
from (
  select id, date, another_info, 
         row_number() over (partition by id order by date desc) as rn
  from the_table
) t
where rn = 1
order by id;

Die Lösung mit einer Fensterfunktion ist in den meisten Fällen schneller als die Verwendung einer Unterabfrage.


4
upvoted! Es wird jedoch ein Index für die Datumsabnahme benötigt. Ich habe immer angenommen, dass Indizes in beide Richtungen durchsuchbar sind. Ein aufsteigender Standard-Primärschlüsselindex für das Datum sollte für eine Abwärtsbewegung im selben Feld gut funktionieren. In meinem Fall habe ich zusammengesetzte Schlüssel (ID, Datum). zusammengesetzte Schlüssel, die Probleme verursachen?
PirateApp

19
select * 
from bar 
where (id,date) in (select id,max(date) from bar group by id)

Getestet in PostgreSQL, MySQL


-5

Gruppieren Sie nach ID und verwenden Sie alle Aggregatfunktionen, um die Kriterien des letzten Datensatzes zu erfüllen. Zum Beispiel

select  id, max(date), another_info
from the_table
group by id, another_info

4
Auch dies wird nicht die tatsächliche Ausgabe geben
Vivek S.

Was fehlt mir hier?
Amal Ts

Sie unterscheiden Gruppen anhand von another_info, sodass diese nicht nur nach ID gruppiert werden. Wenn Sie stattdessen eine Aggregatfunktion für another_info verwenden, um eine korrekte Gruppierung zu erhalten, gibt die Aggregatfunktion (z. B. max ()) nicht den Wert another_info für die Zeile mit dem Maximum (Datum) zurück. In der Tat sind diese beiden Beobachtungen der Grund dafür, dass dies in erster Linie eine Frage ist.
Gwideman
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.