ProgrammierungBackend-Entwickler

Wie implementiert man die Berechnung kumulativer (laufender) Summen in SQL ohne Windows-Funktionen, unter Berücksichtigung der Leistung bei Tausenden oder Millionen von Zeilen?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

Die Berechnung kumulativer Summen und laufender Beträge wurde traditionell in SQL über Fensterfunktionen (zum Beispiel SUM() OVER(ORDER BY ...)) gelöst. In früheren oder vereinfachten Versionen von DBMS sind jedoch nur Unterabfragen und Gruppierungen verfügbar. Historisch haben DB-Architekten nach Alternativen gesucht, bevor der SQL:2003-Standard mit Unterstützung für Fensterfunktionen eingeführt wurde.

Problem — In Abwesenheit von Fensterfunktionen muss für jede Zeile die Summe aller vorherigen Werte explizit berechnet werden, was zu O(N^2) verschachtelten Abfragen bei ausreichend großen Auswahlmengen führt, es sei denn, es werden Tricks angewendet.

Lösung:

Üblicherweise werden korrelierte Unterabfragen oder temporäre Tabellen mit Aktualisierung der Werte verwendet:

Codebeispiel:

-- Kumulative Summe mit korrelierter Abfrage SELECT t1.id, t1.amount, ( SELECT SUM(t2.amount) FROM transactions t2 WHERE t2.id <= t1.id ) AS running_total FROM transactions t1 ORDER BY t1.id; -- Über eine temporäre Tabelle mit manueller Aktualisierung des Wertes CREATE TEMPORARY TABLE temp_running (id INT, amount INT, running_total INT); -- Durchlaufen der Zeilen mit Hilfe externen Codes (zum Beispiel pl/pgsql), während die Summen nacheinander hinzugefügt werden

Wichtige Merkmale:

  • Die Methode funktioniert nur, wenn es ein einzigartiges Sortierkriterium gibt (id, Erstellungsdatum)
  • Korrelierte Unterabfragen skalieren schlecht — exponentielles Wachstum der Ausführungszeit
  • Für große Datenmengen ist es logischer, ETL mit Aggregation außerhalb von SQL oder mit prozeduralen Mitteln zu verwenden

Fangfragen

Gewährleistet das ORDER BY in einer korrelierten Unterabfrage eine garantierte Sortierung?

Nein — die Subabfrage beeinflusst nicht unbedingt das Ergebnis. Die Sortierung der Endauswahl wird immer extern in der Hauptabfrage festgelegt: das Ergebnis hängt nur von der Filterung durch WHERE ab.

Kann die Berechnung der kumulativen Summe in diesem Ansatz parallelisiert werden?

Nein — die Reihenfolge ist sehr wichtig, insbesondere bei Berechnungen, die von vorhergehenden Zeilen abhängen, weshalb eine einfache Parallelisierung in gewöhnlichem SQL nicht möglich ist.

Warum ist eine korrelierte Unterabfrage bei einer großen Anzahl von Zeilen so langsam?

Weil für jede Zeile erneut die Summe über die Menge der vorhergehenden Zeilen berechnet wird. Dies führt zu O(N^2) Operationen. Bei einem Beispiel mit 100.000 Zeilen kann dies bereits Minuten oder sogar Stunden in Anspruch nehmen.

Typische Fehler und Anti-Pattern

  • Falsche Filterung nach id statt nach dem tatsächlichen Datum — die Summen „springen“ bei Lücken in der id
  • Versuch, Summierungen ohne Sortierung der Daten durchzuführen
  • Verwendung dieses Ansatzes für riesige Tabellen, wenn ETL oder partitionierte Verarbeitung erforderlich ist

Beispiel aus dem Leben

Negativer Fall

Ein Analyst berechnete den täglichen kumulativen Umsatz nach Datum über eine korrelierte Unterabfrage, während in der Tabelle zeitweise gelöschte ids (Lücken) auftauchten. Die Endsumme hatte sprunghafte Einbrüche und hing nicht vom Datum, sondern von der Reihenfolge der ids ab.

Vorteile:

  • Funktioniert für kleine Abfragen, keine Fensterfunktionen erforderlich

Nachteile:

  • Daten sind inkorrekt, sie werden nicht so berechnet, wie erwartet
  • Schwierige Wartung

Positiver Fall

Ein Ingenieur übertrug die Verarbeitung der kumulativen Summe in ein ETL-Skript (Python/pandas), und lud die Endwerte in eine separate Tabelle, wobei nur neue Einträge synchronisiert wurden. Die Ergebnisse sind immer nach Datum abgestimmt, der Code läuft schnell und mit Millionen von Datensätzen.

Vorteile:

  • Zuverlässigkeit, Möglichkeit zur Nachberechnung ohne Ausfallzeiten
  • Unterstützung großer Datenmengen

Nachteile:

  • Komplexere Landschaft — externe Verarbeitungstools sind erforderlich