Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| modul:m290_guko:learningunits:lu10:theorie:a_einfuehrung [2025/11/05 22:47] – gkoch | modul:m290_guko:learningunits:lu10:theorie:a_einfuehrung [2025/11/06 00:18] (aktuell) – gkoch | ||
|---|---|---|---|
| Zeile 24: | Zeile 24: | ||
| === Wozu braucht man das? === | === Wozu braucht man das? === | ||
| - | * **Datenanalyse & Reporting** (z.B. Lageberichte | + | * **Datenanalyse & Reporting** – Beispiel (Einbrüche ZH): Wie viele Fälle gab es pro Jahr? |
| - | * **Business Intelligence** (Trends, Hotspots je Gemeinde/ | + | * **Nutzen:** Klare Jahreskurven für **Berichte**, |
| - | * **Produkt-/ | + | * **Business Intelligence |
| - | * **Entscheidungsgrundlagen** (Ressourcen planen, Präventionsmassnahmen priorisieren) | + | * **Nutzen:** **Prioritäten** setzen (Präventionskampagnen, Ressourceneinsatz, |
| + | * **Produkt-/ | ||
| + | * **Nutzen:** Das **Backend** liefert fertige Kennzahlen; die **Frontend-Logik** bleibt schlank und schnell. | ||
| Zeile 47: | Zeile 49: | ||
| </ | </ | ||
| - | ==== 1.2 Einstiegsbeispiele | + | ==== 1.2 Einstiegsbeispiele ==== |
| === Anzahl unterschiedlicher Gemeinden im Datensatz === | === Anzahl unterschiedlicher Gemeinden im Datensatz === | ||
| Zeile 70: | Zeile 72: | ||
| ===== 2. GROUP BY – Daten zu Gruppen zusammenfassen ===== | ===== 2. GROUP BY – Daten zu Gruppen zusammenfassen ===== | ||
| + | |||
| + | {{ : | ||
| <WRAP round 80% box center> | <WRAP round 80% box center> | ||
| Zeile 94: | Zeile 98: | ||
| === WHERE vs. HAVING === | === WHERE vs. HAVING === | ||
| - | WHERE filtert einzelne Zeilen vor dem Gruppieren. | + | * **WHERE** filtert einzelne Zeilen vor dem Gruppieren. |
| - | HAVING filtert fertige Gruppen nach dem Gruppieren. | + | * **HAVING** filtert fertige Gruppen nach dem Gruppieren. |
| + | |||
| <WRAP round 80% box center> | <WRAP round 80% box center> | ||
| Beispiel: Nur Jahre ab 2018 berücksichtigen (WHERE), und nur Gruppen mit Total > 1'000 zeigen (HAVING) | Beispiel: Nur Jahre ab 2018 berücksichtigen (WHERE), und nur Gruppen mit Total > 1'000 zeigen (HAVING) | ||
| Zeile 107: | Zeile 113: | ||
| //Ergebnis: In den Jahren 2018, 2019 und 2024 haben über 15000 Einbrüche total stattgefunden.// | //Ergebnis: In den Jahren 2018, 2019 und 2024 haben über 15000 Einbrüche total stattgefunden.// | ||
| </ | </ | ||
| - | === Alias in GROUP BY === | + | |
| - | MySQL: Alias kann verwendet werden. Für Portabilität (z.B. andere SQL‑Dialekte): | + | |
| ==== 2.1 Beispiele: Gruppieren nach einem Kriterium ==== | ==== 2.1 Beispiele: Gruppieren nach einem Kriterium ==== | ||
| <WRAP round 80% box center> | <WRAP round 80% box center> | ||
| - | **a) Total Einbrüche pro Jahr** <code sql> | + | **Total Einbrüche pro Jahr** <code sql> |
| SELECT ausgangsjahr, | SELECT ausgangsjahr, | ||
| SUM(straftaten_total) AS total_faelle | SUM(straftaten_total) AS total_faelle | ||
| Zeile 121: | Zeile 126: | ||
| **Ergebnis (Auszug)** | **Ergebnis (Auszug)** | ||
| ^ ausgangsjahr ^ total_faelle ^ | ^ ausgangsjahr ^ total_faelle ^ | ||
| - | | 2019 | 5080 | | + | | 2009 | 29972 | |
| - | | 2020 | 4525 | | + | | 2010 | 26770 | |
| - | | 2021 | 4789 | | + | | 2011 | 24394 | |
| + | ... etc. | ||
| </ | </ | ||
| - | <WRAP round 80% box center> | ||
| - | **b) Anzahl erfasste Gemeinden pro Jahr** | ||
| - | <code sql> | ||
| - | 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 | | ||
| - | </ | ||
| ==== 2.2 Beispiele: Gruppieren nach mehreren Kriterien ==== | ==== 2.2 Beispiele: Gruppieren nach mehreren Kriterien ==== | ||
| Zeile 153: | Zeile 145: | ||
| **Ergebnis (Auszug)** | **Ergebnis (Auszug)** | ||
| ^ ausgangsjahr ^ tatbestand ^ total_faelle ^ | ^ ausgangsjahr ^ tatbestand ^ total_faelle ^ | ||
| - | | 2020 | Einbruch | + | | 2023 | Einschleichdiebstahl |
| - | | 2020 | Einschleichen | + | | 2024 | Einbruchdiebstahl |
| - | | 2021 | Einbruch | + | | 2024 | Einbrüche insgesamt |
| + | ... etc. | ||
| </ | </ | ||
| - | ===== 3. HAVING – Gruppen | + | ===== 3. HAVING – Gruppen filtern ===== |
| WHERE kann **keine** Aggregatfunktionen enthalten. Wenn Sie **Ergebnisgruppen** (nach GROUP BY) filtern wollen, verwenden Sie **HAVING**. | WHERE kann **keine** Aggregatfunktionen enthalten. Wenn Sie **Ergebnisgruppen** (nach GROUP BY) filtern wollen, verwenden Sie **HAVING**. | ||
| <WRAP round 80% box center> | <WRAP round 80% box center> | ||
| - | **Jahre mit über 5'000 Fällen insgesamt** <code sql> | + | **Jahre mit über 25'000 Fällen insgesamt** <code sql> |
| SELECT ausgangsjahr, | SELECT ausgangsjahr, | ||
| SUM(straftaten_total) AS total_faelle | SUM(straftaten_total) AS total_faelle | ||
| FROM zh_einbrueche.einbrueche | FROM zh_einbrueche.einbrueche | ||
| GROUP BY ausgangsjahr | GROUP BY ausgangsjahr | ||
| - | HAVING SUM(straftaten_total) > 5000 | + | HAVING SUM(straftaten_total) > 25000 |
| ORDER BY total_faelle DESC; </ | ORDER BY total_faelle DESC; </ | ||
| **Ergebnis (Auszug)** | **Ergebnis (Auszug)** | ||
| ^ ausgangsjahr ^ total_faelle ^ | ^ ausgangsjahr ^ total_faelle ^ | ||
| - | | 2013 | 6240 | | + | | 2009 | 29972 | |
| - | | 2012 | 6115 | | + | | 2012 | 28730 | |
| - | </ | + | | 2010 | 26770 | |
| - | + | ||
| - | <WRAP round 80% box center> | + | |
| - | **Abarbeitungsreihenfolge (vereinfacht)** | + | |
| - | FROM → WHERE → GROUP BY → **Aggregatfunktionen** → HAVING → SELECT → ORDER BY. | + | |
| </ | </ | ||
| - | ===== 4. Häufige Stolpersteine (und wie man sie vermeidet) ===== | ||
| - | * SELECT enthält **ungegruppte Spalten** → Fehlermeldung oder Zufallswerte. | ||
| - | → Nur Spalten in GROUP BY **oder** in Aggregaten verwenden. | ||
| - | * **Division durch 0** bei Anteilen/ | ||
| - | → NULLIF(denominator, | ||
| - | * **MySQL‑Spezialität**: | ||
| - | → Ausdruck wiederholen, | ||
| - | * **NULLs**: COUNT(spalte) ignoriert NULL → **bewusste Spaltenwahl!** | ||