Max- Datensatz in JOIN ermitteln

Hallo zusammen,

ich bin neu hier im Forum :slight_smile:

Meine Frage:
Da es leider nicht möglich ist die MAX Aggregatfunktion in einem JOIN zu verwenden, suche ich nach Lösungen um folgende Abfrag zu realisieren.

Zu aller erst die (vereinfachte) Tabellenstruktur:

Person
->Person.id (1)
->Person.status

PersonProgramm
->id (2)
->person_id (1)

PersonProgrammFortschritt
->id
->personProgramm_id (2)

Beziehungen:
Person zu PersonProgramm: 1:n
PersonProgramm zu Person ProgrammFortschritt: 1:n

Nun würde ich gerne zu allen Personen mit dem status 4, jeweils den höchsten PersonProgrammFortschritt einsehen, gemessen an der PersonProgrammFortschritt.id.

Ich kann dies für einzelne Personen mit folgender Abfrage bewerkstelligen:
SELECT * FROM PersonProgrammFortschritt ppf
WHERE ppf.id =
(SELECT max(ppf.id) FROM Person
LEFT JOIN PersonProgramm AS pp ON pp.person_id = person.id
LEFT JOIN PersonProgrammFortschritt AS ppf ON ppf.personProgramm_id = pp.id
WHERE person.id = 1 AND person.status = 4)

Für die Abfrage aller Personen würde mir folgendes einfallen:

SELECT Person.id, max(ppf.id) FROM Person
LEFT JOIN PersonProgram AS pp ON pp.person_id = person.id
LEFT JOIN PersonProgramFortschritt AS ppf ON ppf.personProgramm_id = pp.id
WHERE person.status = 4
GROUP BY person.id

Gibt es ggf. schönere Lösungen oder ist diese mögliche Lösung optimal?

Vielen Dank im voraus.

Ich bin mir nicht 100% sicher, dass ich alles verstanden habe, aber meinst Du sowas?

SELECT pp.person_id, 
       pp.max_ppf_id
FROM person 
  LEFT JOIN (
    SELECT pp.person_id, 
           max(ppf.id) as max_ppf_id
    FROM personprogramm AS pp 
      JOIN personprogrammfortschritt ppf ON ppf.personprogramm_id = pp.id
    group by pp.person_id
  ) as pp ON pp.person_id = person.id
WHERE person.status = 4;

Hi castorp,

danke für die schnelle Antwort.

Mit dem LEFT JOIN komm ich auf jeden Fall weiter, danke für den Vorschlag!
Dies scheint mir eine gute Lösung um den maximal Wert (ID) einer gejointen Tabelle in einem Statement zu ermitteln und gleichzeitig einen Join durchzuführen.

Ich habe die Abfrage noch ein wenig angepasst um alle benötigten Informationen aus der Tabelle “personprogrammfortschritt” zur höhsten ID zu erhalten:

SELECT ppf2.id, ppf2.name, ppf2.vondatum, ppf2.bisdatum -- u.s.w.
FROM person 
  LEFT JOIN (
    SELECT pp.person_id, 
           max(ppf.id) as max_ppf_id
    FROM personprogramm AS pp 
      JOIN personprogrammfortschritt ppf ON ppf.personprogramm_id = pp.id
    group by pp.person_id
  ) as pp ON pp.person_id = person.id
  LEFT JOIN personprogrammfortschritt ppf2 ON ppf2.id = pp.max_ppf_id
WHERE person.status = 4;

Grüße
BladeNeo