Aktuellsten Umsatz je Konto suchen

Für eine Auswertung benötigte ich je Konto die Angaben zum letzten Umsatz, und zwar Zeitpunkt, Betrag und BLZ des Empfängers. Wäre es nur der Zeitpunkt gewesen, wäre es natürlich ein Kinderspiel. Aber zuerst meine Beispiel-Tabelle:

Umsaetze
Konto Buchung Betrag BLZ
18 2014-01-08 13:48:53.527861 -1000 12345678
18 2013-10-08 13:48:53.527861 500 32657890
26 2014-01-08 14:48:53.527861 -1000 12345678
18 2014-07-08 14:13:52.123578 800 21560215
26 2012-01-08 13:48:53.527861 -1000 12345678
34 2014-08-08 16:43:32.846312 -1000 21752468

Den Zeitpunkt des letzten Umsatzes findet man via max leicht heraus:

select konto, max(buchung) from umsaetze group by konto

Dann habe ich versucht, diese Daten mittels JOIN anzureichern – das hat auch funktioniert, die Selektion hat aber ewig gedauert:

select u.konto, u.buchung, u.betrag, u.blz
from umsaetze as u
join (select konto, max(buchung) as buchung from umsaetze group by konto) as l on l.konto=u.konto and l.buchung=u.buchung

Da diese Daten häufig benötigt werden, habe ich den Select weiter optimiert, es ist jetzt nicht mehr auf Anhieb so verständlich wie das gerade genannte Statement, dafür wesentlich performanter:

select u.konto, u.buchung, u.betrag, u.blz
from umsaetze as u
left join umsaetze as l on l.konto=u.konto and l.buchung > u.buchung
where l.konto is null

Was passiert hier?

Zuerst hole ich alle Umsätze, dann joine ich nochmal alle Umsätze dazu, die aktueller sind. Ich nutze einen LEFT JOIN, so dass es je Konto auch einen Datensatz gibt, für die es keine aktuelleren Umsätze gibt. Und genau diesen identifiziere ich in der WHERE-Klausel.

Man kann das ganze auch noch erweitern, wenn man z.B. den aktuellsten Haben-Umsatz haben will, oder aber den letzten Umsatz vor einem Stichtag – hier im Beispiel jetzt mal den letzten Haben-Umsatz des letzten Jahres:

select u.konto, u.buchung, u.betrag, u.blz
from umsaetze as u
left join umsaetze as l on l.konto=u.konto and l.buchung > u.buchung and l.betrag >= 0 and l.buchung < '2014-01-01 00.00:00.000000'
where l.konto is null and u.betrag >= 0 and u.buchung < '2014-01-01 00.00:00.000000'

Man muss nur drauf achten, dass die Bedingungen für den LEFT JOIN und die für die WHERE-Klausel identisch sind.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.