Left join mit dem neusten Treffer aus der rechten Tabelle

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. :slight_smile:

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 Like

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 Like

Vielen Dank, das hat mir sehr geholfen!