Rolf B: mysql, Query optimieren

Beitrag lesen

Hallo Jörg,

Bitte nicht...

Nein nein, entspann Dich, so nicht.

Was Du im Moment hast, ist (mit etwas mehr Einrückungen für bessere Forenlesbarkeit)

LEFT JOIN _table_mahnungen m
     ON ( r.RechnungenID = m.RechnungenID AND m.aktiv = 1)
    AND m.RechnungenID = (SELECT MAX(tmp.RechnungenID)
                          FROM _table_mahnungen tmp
                          WHERE tmp.RechnungenID = r.RechnungenID 
                            AND m.aktiv = 1)

Soweit ich erkennen kann, hat die Mahnungen-Tabelle diese Spalten:

  • RechnungenID - Verknüpfung zu den Rechnungen
  • Mahnstatus - Kann ich nicht einordnen. Könnte die Mahnstufe sein.
  • Mahndatum - Wann wurde gemahnt
  • Faelligkeit - Welches Ultimatum wurde in der Mahnung gestellt
  • aktiv - 1 oder was anderes (vermutlich 0). Du willst nur aktive Mahnungen beachten, warum auch immer. Ist auch egal. Du willst es, du kriegst es!!! 😉

Achtung: Ich habe in deinen Beiträgen keine Spalte gesehen, die klar auf die Mahnstufe hinweist. Ich nehme daher an, dass sich die Mahnstufe in der Spalte Mahnstatus findet. Wenn das nicht stimmt, und es noch eine eigene Spalte für die Mahnstufe gibt, dann musst Du im Folgenden natürlich Mahnstatus durch den korrekten Spaltennahmen für die Mahnstufe ersetzen.

Dein erster Teil ( r.RechnungenID = m.RechnungenID AND m.aktiv = 1) findet alle aktiven Mahnungen zur RechnungenID. Die Klammern brauchst Du hier übrigens nicht, weil es danach mit AND weitergeht.

Aber du willst nur die mit dem höchsten Mahnstatus. Ich nehme an, dass eine Mahnung eindeutig durch das Wertepaar (RechnungenID, Mahnstatus) identifiziert wird. Wenn nicht - dann müssen wir da genauer hinschauen.

Die RechnungenID wird schon abgefragt, jetzt muss noch eine Abfrage auf Mahnstatus hinzukommen. Du musst die Zeile joinen, in der Mahnstatus die maximalen Mahnstufe für diese RechnungenID enthält. Bei der Maximumsuche darfst Du natürlich nur die aktiven Mahnungen berücksichtigen, sonst gehört das Maximum eventuell zu einer inaktiven Mahnung und dann bekommst Du gar nichts.

Dein Join muss also so aussehen:

LEFT JOIN _table_mahnungen m
     ON m.RechnungenID = r.RechnungenID 
    AND m.aktiv = 1
    AND m.Mahnstatus = (SELECT MAX(tmp.Mahnstatus)
                          FROM _table_mahnungen tmp
                          WHERE tmp.RechnungenID = r.RechnungenID 
                            AND tmp.aktiv = 1)

Den Tabellenalias tmp brauchst Du meines Wissens nicht. Probier's mal aus, ich bin nicht ganz sicher. Aber ich meine, dass in einem Subselect alle Spaltenangaben, die ohne explizite Angabe der Tabelle gemacht werden, auf den Subselect bezogen werden und nicht auf den äußeren Select.

Rolf

--
sumpsi - posui - obstruxi