modul:m290_guko:learningunits:lu10:theorie:a_einfuehrung

Dies ist eine alte Version des Dokuments!


LU10: Aggregatfunktionen (MySQL) – mit Beispielen aus «Einbrüche Kanton Zürich»

Datensatz: Anzahl Einbrüche nach Gemeinden und Stadtkreisen des Kantons Zürich

Um die Code-Beispiele nachvollziehen zu können, brauchen Sie die Datenbank zh_einbrueche, die Sie hier als .zip-File downloaden können: Zip-File mit Datenbank (sql-File) zu Einbrüchen im Kanton Zürich. 1)

Was sind Aggregatfunktionen?

Aggregatfunktionen berechnen einen zusammengefassten Wert über mehrere Zeilen (Records). Typische Aufgaben:

  • Zählen (Wie viele Einbrüche?)
  • Summieren (Wie viele Fälle insgesamt?)
  • Durchschnitt (Ø‑Häufigkeitszahl pro Jahr)
  • Minimum/Maximum (geringste/höchste Zahl pro Gemeinde)

Wozu braucht man das?

  • Datenanalyse & Reporting (z.B. Lageberichte für Polizei/Medien)
  • Business Intelligence (Trends, Hotspots je Gemeinde/Jahr)
  • Produkt-/Web‑Integration (APIs liefern Rohdaten → Aggregation im Backend/SQL spart App‑Logik)
  • Entscheidungsgrundlagen (Ressourcen planen, Präventionsmassnahmen priorisieren)
Funktion Zweck NULLs
COUNT(*) Zeilen zählen zählt alle Zeilen
COUNT(spalte) Nicht‑NULL‑Werte zählen ignoriert NULL
SUM(spalte) Summe ignoriert NULL
AVG(spalte) Durchschnitt ignoriert NULL
MIN(spalte) Minimum ignoriert NULL
MAX(spalte) Maximum ignoriert NULL

Syntax

SELECT AGGREGATFUNKTION(ausdruck) AS alias
FROM zh_einbrueche.einbrueche;

Anzahl unterschiedlicher Gemeinden im Datensatz

SELECT COUNT(DISTINCT gemeindename) AS anzahl_gemeinden
FROM zh_einbrueche.einbrueche; 

Ergebnis (Auszug)

anzahl_gemeinden
161

Höchster Einzelwert pro Zeile (Totalfälle)

SELECT MAX(straftaten_total) AS max_faelle_in_einer_zeile
FROM zh_einbrueche.einbrueche; 

Ergebnis (Auszug)

max_faelle_in_einer_zeile
1060

Warum ist GROUP BY wichtig? Ohne GROUP BY erhalten Sie einen Aggregatwert über alle Zeilen. Mit GROUP BY erhalten Sie je Gruppe eine Zeile (z.B. pro Jahr, pro Gemeinde oder pro Kombination aus Jahr+Gemeinde). Das ist zentral für Trends, Rankings und Vergleiche.

Regeln (MySQL‑kompatibel, Standard‑konform formuliert):

  • In SELECT dürfen neben Aggregaten nur Spalten stehen, die auch im GROUP BY vorkommen.
  • WHERE filtert Zeilen vor dem Gruppieren. HAVING filtert Gruppen nach dem Gruppieren.
  • MySQL erlaubt teils Aliasse in GROUP BY (z.B. GROUP BY jahr nach SELECT YEAR(…) AS jahr). Für bessere Portabilität: Ausdruck wiederholen.

a) Total Einbrüche pro Jahr

SELECT ausgangsjahr,
SUM(straftaten_total) AS total_faelle
FROM   zh_einbrueche.einbrueche
GROUP  BY ausgangsjahr
ORDER  BY ausgangsjahr; 

Ergebnis (Auszug)

ausgangsjahr total_faelle
2019 5080
2020 4525
2021 4789

b) Anzahl erfasste Gemeinden pro Jahr

SELECT ausgangsjahr,
COUNT(DISTINCT gemeindename) AS anzahl_gemeinden
FROM   zh_einbrueche.einbrueche
GROUP  BY ausgangsjahr
ORDER  BY ausgangsjahr; 

Ergebnis (Auszug)

ausgangsjahr anzahl_gemeinden
2019 171
2020 171
2021 171

Total pro Jahr und Tatbestand (z.B. Einbruch, Einschleichen)

SELECT ausgangsjahr,
tatbestand,
SUM(straftaten_total) AS total_faelle
FROM   zh_einbrueche.einbrueche
GROUP  BY ausgangsjahr, tatbestand
ORDER  BY ausgangsjahr, tatbestand; 

Ergebnis (Auszug)

ausgangsjahr tatbestand total_faelle
2020 Einbruch 3100
2020 Einschleichen 1425
2021 Einbruch 3250

WHERE kann keine Aggregatfunktionen enthalten. Wenn Sie Ergebnisgruppen (nach GROUP BY) filtern wollen, verwenden Sie HAVING.

Jahre mit über 5'000 Fällen insgesamt

SELECT ausgangsjahr,
SUM(straftaten_total) AS total_faelle
FROM   zh_einbrueche.einbrueche
GROUP  BY ausgangsjahr
HAVING SUM(straftaten_total) > 5000
ORDER  BY total_faelle DESC; 

Ergebnis (Auszug)

ausgangsjahr total_faelle
2013 6240
2012 6115

Abarbeitungsreihenfolge (vereinfacht) FROM → WHERE → GROUP BY → Aggregatfunktionen → HAVING → SELECT → ORDER BY.

* SELECT enthält ungegruppte Spalten → Fehlermeldung oder Zufallswerte.

→ Nur Spalten in GROUP BY **oder** in Aggregaten verwenden.

* Division durch 0 bei Anteilen/Quoten.

→ NULLIF(denominator,0) verwenden.

* MySQL‑Spezialität: Alias in GROUP BY ist erlaubt, aber nicht portabel.

→ Ausdruck wiederholen, wenn Portabilität wichtig ist.

* NULLs: COUNT(spalte) ignoriert NULL → bewusste Spaltenwahl!

LU10: Aggregatfunktionen (MySQL) – mit Beispielen aus «Einbrüche Kanton Zürich»

Datensatz: *Anzahl Einbrüche nach Gemeinden und Stadtkreisen des Kantons Zürich*

Tabellen- & Feldübersicht (vereinfacht) Datenbank: zh_einbrueche • Tabelle: einbrueche

Feld Typ (MySQL) Pflicht Bedeutung
id BIGINT UNSIGNED ja (PK) künstlicher Primärschlüssel
ausgangsjahr YEAR ja Berichtsjahr der PKS (nicht Tatzeitpunkt)
gemeinde_bfs_nr INT ja BFS-Nummer der Gemeinde
gemeindename VARCHAR(100) ja Gemeindename
stadtkreis_bfs_nr INT nein Nur Stadt Zürich: BFS-Nr. des Stadtkreises
stadtkreis_name VARCHAR(100) nein Nur Stadt Zürich: Name des Stadtkreises
gesetz_nummer DECIMAL(6,1) ja Gesetzesnummer des Tatbestands
gesetz_abk VARCHAR(16) ja Gesetzesabkürzung (z.B. StGB)
tatbestand VARCHAR(100) ja z.B. Einbruch, Einschleichen
straftaten_total INT ja Vollendet + Versucht
straftaten_vollendet INT ja Vollendete Taten
straftaten_versucht INT ja Versuch
einwohner INT ja Bevölkerungszahl (Ende Vorjahr)
haeufigkeitszahl DECIMAL(10,2) ja Taten pro 1'000 Einwohner

Was sind Aggregatfunktionen? Aggregatfunktionen berechnen einen zusammengefassten Wert über mehrere Zeilen (Records). Typische Aufgaben:

* Zählen (Wie viele Einbrüche?) * Summieren (Wie viele Fälle insgesamt?) * Durchschnitt (Ø‑Häufigkeitszahl pro Jahr) * Minimum/Maximum (geringste/höchste Zahl pro Gemeinde)

Wozu braucht man das?

* Datenanalyse & Reporting (z.B. Lageberichte für Polizei/Medien) * Business Intelligence (Trends, Hotspots je Gemeinde/Jahr) * Produkt-/Web‑Integration (APIs liefern Rohdaten → Aggregation im Backend/SQL spart App‑Logik) * Entscheidungsgrundlagen (Ressourcen planen, Präventionsmassnahmen priorisieren)

Funktion Zweck NULLs Beispiel
COUNT(*) Zeilen zählen zählt alle Zeilen Anzahl Zeilen im Jahr
COUNT(spalte) Nicht‑NULL‑Werte zählen ignoriert NULL z.B. vorhandene Werte in einer Spalte
SUM(spalte) Summe ignoriert NULL Total aller straftaten_total
AVG(spalte) Durchschnitt ignoriert NULL Ø haeufigkeitszahl pro Jahr
MIN(spalte) Minimum ignoriert NULL tiefste straftaten_total pro Gemeinde
MAX(spalte) Maximum ignoriert NULL höchste straftaten_total pro Gemeinde

Syntax

SELECT AGGREGATFUNKTION([DISTINCT|ALL] ausdruck) AS alias
FROM zh_einbrueche.einbrueche;

MySQL‑Standard ist ALL (= Duplikate werden mitgerechnet). DISTINCT rechnet nur mit einzigartigen Werten.

Anzahl unterschiedlicher Gemeinden im Datensatz

SELECT COUNT(DISTINCT gemeindename) AS anzahl_gemeinden
FROM zh_einbrueche.einbrueche; 

Ergebnis (Auszug)

anzahl_gemeinden
171

Höchster Einzelwert pro Zeile (Totalfälle)

SELECT MAX(straftaten_total) AS max_faelle_in_einer_zeile
FROM zh_einbrueche.einbrueche; 

Ergebnis (Auszug)

max_faelle_in_einer_zeile
420

Warum ist GROUP BY wichtig? Ohne GROUP BY erhalten Sie einen Aggregatwert über alle Zeilen. Mit GROUP BY erhalten Sie je Gruppe eine Zeile (z.B. pro Jahr, pro Gemeinde oder pro Kombination aus Jahr+Gemeinde). Das ist zentral für Trends, Rankings und Vergleiche.

Regeln (MySQL‑kompatibel, Standard‑konform formuliert):

* In SELECT dürfen neben Aggregaten nur Spalten stehen, die auch im GROUP BY vorkommen. * WHERE filtert Zeilen vor dem Gruppieren. HAVING filtert Gruppen nach dem Gruppieren. * MySQL erlaubt teils Aliasse in GROUP BY (z.B. GROUP BY jahr nach SELECT YEAR(…) AS jahr). Für bessere Portabilität: Ausdruck wiederholen.

a) Total Einbrüche pro Jahr

SELECT ausgangsjahr,
SUM(straftaten_total) AS total_faelle
FROM   zh_einbrueche.einbrueche
GROUP  BY ausgangsjahr
ORDER  BY ausgangsjahr; 

Ergebnis (Auszug)

ausgangsjahr total_faelle
2019 5080
2020 4525
2021 4789

b) Anzahl erfasste Gemeinden pro Jahr

SELECT ausgangsjahr,
COUNT(DISTINCT gemeindename) AS anzahl_gemeinden
FROM   zh_einbrueche.einbrueche
GROUP  BY ausgangsjahr
ORDER  BY ausgangsjahr; 

Ergebnis (Auszug)

ausgangsjahr anzahl_gemeinden
2019 171
2020 171
2021 171

Total pro Jahr und Tatbestand (z.B. Einbruch, Einschleichen)

SELECT ausgangsjahr,
tatbestand,
SUM(straftaten_total) AS total_faelle
FROM   zh_einbrueche.einbrueche
GROUP  BY ausgangsjahr, tatbestand
ORDER  BY ausgangsjahr, tatbestand; 

Ergebnis (Auszug)

ausgangsjahr tatbestand total_faelle
2020 Einbruch 3100
2020 Einschleichen 1425
2021 Einbruch 3250

WHERE kann keine Aggregatfunktionen enthalten. Wenn Sie Ergebnisgruppen (nach GROUP BY) filtern wollen, verwenden Sie HAVING.

Jahre mit über 5'000 Fällen insgesamt

SELECT ausgangsjahr,
SUM(straftaten_total) AS total_faelle
FROM   zh_einbrueche.einbrueche
GROUP  BY ausgangsjahr
HAVING SUM(straftaten_total) > 5000
ORDER  BY total_faelle DESC; 

Ergebnis (Auszug)

ausgangsjahr total_faelle
2013 6240
2012 6115

Abarbeitungsreihenfolge (vereinfacht) FROM → WHERE → GROUP BY → Aggregatfunktionen → HAVING → SELECT → ORDER BY.

* SELECT enthält ungegruppte Spalten → Fehlermeldung oder Zufallswerte.

→ Nur Spalten in GROUP BY **oder** in Aggregaten verwenden.

* Division durch 0 bei Anteilen/Quoten.

→ NULLIF(denominator,0) verwenden.

* MySQL‑Spezialität: Alias in GROUP BY ist erlaubt, aber nicht portabel.

→ Ausdruck wiederholen, wenn Portabilität wichtig ist.

* NULLs: COUNT(spalte) ignoriert NULL → bewusste Spaltenwahl!


1)
Datenquelle: Kantonspolizei des Kantons Zürich
  • modul/m290_guko/learningunits/lu10/theorie/a_einfuehrung.1762363243.txt.gz
  • Zuletzt geändert: 2025/11/05 18:20
  • von gkoch