Hi,
Ich habe ein Problem, eine Abfrage hinzukriegen. Hier erstmal zwei Beispiel-Tabellen dazu:
SELECT * FROM geraete
id geraet
1 Computer
2 Laptop
3 Router
SELECT * FROM protokolle
id geraet_id protokoll
1 1 Fehler 27
2 1 Fehler 32
3 2 Fehler 12
4 3 Fehler 44
Jetzt möchte ich erreichen, dass zu jedem Gerät nur der letzte Protokolleintrag angezeigt wird. In folgendem Beispiel erscheint der Computer zwei mal. Die erste Zeile soll hier nicht dargestellt werden.
SELECT * FROM geraete LEFT JOIN protokolle ON geraete.id = protokolle.geraet_id
id geraet id geraet_id protokoll
1 Computer 1 1 Fehler 27
1 Computer 2 1 Fehler 32
2 Laptop 3 2 Fehler 12
3 Router 4 3 Fehler 44
Wie kann ich das erreichen?
Vielen Dank im Vorraus. Und seid nicht zu hart. Bin noch Anfänger bei dem Thema.
du kannst left join (subselect) alias on … verwenden. Im Subselect mußt Du nun entscheiden, welchen der beiden Datensätze Du haben willst. Also min(), max(), DISTINCT, …
1 „Gefällt mir“
Du hast nicht gesagt wie “der letzte” Datensatz ermittelt werden soll. Nachdem es in Protokolle keinen Zeitstempel gibt, geh’ ich mal davon aus, dass z.B. die ID die Reihenfolge bestimmt.
In Postgres kann man das recht effizient mit distinct on ()
machen:
SELECT g.*, p.id, p.protokoll
FROM geraete g
LEFT JOIN (
select distinct on (geraet_id) *
from protokolle
order by geraet_id, id desc
) p ON g.id = p.geraet_id;
Wenn Du lieber etwas hättest was standard SQL ist, dann kann man z.B. eine sog. Window Funktion verwenden:
SELECT g.*, p.id, p.protokoll
FROM geraete g
LEFT JOIN (
select *, row_number() over (partition by geraet_id order by id desc) as rn
from protokolle
) p ON g.id = p.geraet_id and p.rn = 1
1 „Gefällt mir“
Vielen Dank, das hat mir sehr geholfen!