mitmario.dev

Auswerten mit SQL

Python Sandbox 3 Min Lesezeit 4 BeispieleLektion 5 von 6

Du willst wissen, wofür in einer Woche wie viel Geld draufgegangen ist. Nach Kategorien aufgeteilt. In Lektion 7.5 hast du das mit einem Dictionary und einer Schleife gelöst. Jetzt liegen die Ausgaben aber in einer Datenbank, und die kann selbst zusammenzählen. Bei Python kommen dann nur noch die fertigen Summen an.

Die Beispiele verwenden dieselbe Woche wie damals, nur stehen die Beträge jetzt in Cent da. haushalt.py legt die Datenbank bei jedem Start neu an.

In Python gruppiert

In Python gruppiert
from haushalt import oeffnen

verbindung = oeffnen()
zeilen = verbindung.execute("SELECT kategorie, betrag FROM ausgaben").fetchall()
verbindung.close()

summen = {}
for kategorie, betrag in zeilen:
    summen[kategorie] = summen.get(kategorie, 0) + betrag
for kategorie, cent in summen.items():
    print(f"{kategorie}: {cent / 100:.2f} Euro")

Zuerst der Weg, den du schon kennst. Die Abfrage holt jede einzelne Ausgabe aus der Datenbank. Danach zählt die Schleife mit summen.get(kategorie, 0) + betrag alles zusammen. Heraus kommen 50,40 Euro für Lebensmittel, 25,50 für Freizeit und 2,90 für Mobilität.

Das funktioniert. Es ist nur ein Umweg, weil jede Zeile erst einzeln aus der Datenbank geholt wird, nur damit Python sie danach wieder zusammenzählt. Bei fünf Ausgaben ist das egal. Bei fünfzigtausend nicht mehr.

In SQL gruppiert

In SQL gruppiert
from haushalt import oeffnen

verbindung = oeffnen()
zeilen = verbindung.execute("""
    SELECT kategorie, SUM(betrag), COUNT(*) FROM ausgaben
    GROUP BY kategorie
    ORDER BY kategorie
""").fetchall()
verbindung.close()

print(zeilen)
for kategorie, cent, anzahl in zeilen:
    print(f"{kategorie}: {cent / 100:.2f} Euro ({anzahl})")

Neu ist GROUP BY kategorie, also „gruppiere nach Kategorie“. Alle Ausgaben mit derselben Kategorie landen in einer Gruppe, und für jede Gruppe gibt es im Ergebnis genau eine Zeile.

SUM(betrag) rechnet die Beträge einer Gruppe zusammen und COUNT(*) zählt, wie viele Ausgaben drin sind. Daneben dürfen nur Spalten stehen, nach denen gruppiert wird. Hier ist das die Kategorie.

In der ersten Zeile der Ausgabe siehst du, was bei Python ankommt. Drei Tupel, eins pro Kategorie, jeweils mit Summe und Anzahl. Die Summen sind dieselben wie oben. Nur braucht es dafür jetzt keine Schleife und kein Dictionary mehr, sondern drei Zeilen SQL.

Sortiert wird wie gewohnt mit ORDER BY, und das klappt auch mit der Summe selbst. Mit ORDER BY SUM(betrag) DESC steht die teuerste Kategorie ganz oben.

Erst aussortieren, dann gruppieren

Nur der September
from haushalt import oeffnen

verbindung = oeffnen()
print(verbindung.execute("""
    SELECT kategorie, SUM(betrag) FROM ausgaben
    WHERE datum < '2026-10-01'
    GROUP BY kategorie
    ORDER BY kategorie
""").fetchall())
print(verbindung.execute(
    "SELECT SUM(betrag), COUNT(*) FROM ausgaben WHERE datum < '2026-10-01'"
).fetchone())
verbindung.close()

Soll nur der September zählen, kommt ein WHERE dazu. Es steht vor dem GROUP BY. In dieser Reihenfolge arbeitet auch die Datenbank. Erst fliegen die Ausgaben aus dem Oktober raus, dann wird gruppiert. Freizeit hat deshalb nur noch 18 Euro und Lebensmittel 31,80.

Die zweite Abfrage hat dasselbe WHERE, aber kein GROUP BY. Alles, was übrig bleibt, zählt dann als eine einzige Gruppe. Das ergibt 52,70 Euro aus drei Ausgaben. Das ist die Gesamtsumme, die unter die Übersicht gehört, und weil beide Abfragen dasselbe WHERE haben, passt sie auch sicher zu den Zeilen darüber.

Ohne GROUP BY

Ohne GROUP BY
from haushalt import oeffnen

verbindung = oeffnen()
zeilen = verbindung.execute("SELECT kategorie, SUM(betrag), COUNT(*) FROM ausgaben").fetchall()
verbindung.close()

print(zeilen)
for kategorie, cent, anzahl in zeilen:
    print(f"{kategorie}: {cent / 100:.2f} Euro ({anzahl})")

Hier fehlt das GROUP BY. Das passiert schnell. Viele Datenbanken melden in so einem Fall einen Fehler, SQLite dagegen rechnet einfach los.

Ohne GROUP BY ist die ganze Tabelle eine einzige Gruppe. SUM und COUNT rechnen also über alle fünf Ausgaben, und für kategorie nimmt SQLite den Wert aus irgendeiner Zeile. So entsteht die Zeile „Lebensmittel: 78.80 Euro (5)“. Sieht aus wie ein Ergebnis. Tatsächlich ist es die Summe der ganzen Woche mit einer zufälligen Kategorie davor.

Bekommst du statt einer Übersicht nur eine einzige Zeile, fehlt meistens das GROUP BY.

Python oder SQL

Beide Wege rechnen richtig. Liegen die Daten schon in einer Datenbank und brauchst du Summen, Anzahlen oder den größten Wert pro Gruppe, ist SQL meistens einfacher. Die Abfrage ist kürzer als jede Schleife, und zurück kommen nur die paar Zeilen, die du wirklich brauchst. Auch wenn in der Tabelle hunderttausend Buchungen stehen.

Manche Regeln lassen sich in SQL aber nur umständlich schreiben, etwa die Stichwörter für die Kategorien aus Lektion 12.6. Dann bleibt man besser bei Python. Und kommen die Daten gar nicht aus einer Datenbank, stellt sich die Frage sowieso nicht.

Was die Aufgabe will

Das Haushaltsbuch holt sich seine Monatsübersicht diesmal direkt aus der Datenbank. Eine Zeile pro Kategorie und eine für die Gesamtsumme. Ganz ohne Schleife.

Zum Mitnehmen

GROUP BY fasst alle Zeilen mit demselben Wert zu einer Gruppe zusammen, und SUM() und COUNT(*) rechnen für jede Gruppe Summe und Anzahl aus. WHERE sortiert vorher aus, ORDER BY sortiert hinterher, auch nach einer Summe. Fehlt GROUP BY, rechnet SQLite über die ganze Tabelle und setzt ohne Warnung den Wert irgendeiner Zeile daneben.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 4 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, dein Code läuft auf einem Server

    Öffnet sich mit dem Basis Konto.