====== Aggregationen ====== ===== Group-Funktionen ===== Auch Aggregatfunktionen genannt, berechnen einen einzigen Wert aus einer Menge von Zeilen. ^ Funktion ^ Beschreibung ^ | ''COUNT(*)'' | Anzahl der Zeilen | | ''COUNT(spalte)'' | Anzahl der nicht Null-Werte | | ''SUM(spalte)'' | Summe der Spalteninhalte \\ Erwartet nur Zahlen oder Null | | ''AVG(spalte)'' | Durchschnitt der Spalteninhalte \\ Erwartet nur Zahlen oder Null | | ''MAX(spalte)'' | Größter Wert \\ Kann angewendet werden auf Zahlen, Datum und Text (VARCHAR2) \\ Funktioniert auf allen sortierbaren Datentypen | | ''MIN(spalte)'' | Kleinster Wert \\ Kann angewendet werden auf Zahlen, Datum und Text (VARCHAR2) \\ Funktioniert auf allen sortierbaren Datentypen | | ''LISTAGG(spalte, trennzeichen)'' | Werte zu einem String zusammenfassen | | ''STDDEV(spalte)'' | Standardabweichung (Die Wurzel der Varianz) \\ Kleine Standardabweichung = Werte liegen eng beieinander \\ Große Standardabweichung = Werte streuen stark | | ''VARIANCE(spalte)'' | Varianz (Durchschnitt der quadrierten Abweichungen vom Mittelwert) | **Wichtig!** * ''NULL''-Werte werden von allen Funktionen **außer** ''COUNT(*)'' ignoriert * Ohne ''GROUP BY'' wird die gesamte Tabelle als eine Gruppe behandelt * Spalten im ''SELECT'', die keine Aggregatfunktion sind, **müssen** im ''GROUP BY'' stehen **Beispiel:** -- Liefert Gehaltsinfos der Departments SELECT department_id, COUNT(*) AS anzahl, AVG(salary) AS durchschnittsgehalt, MAX(salary) AS hoechstgehalt FROM employees GROUP BY department_id HAVING AVG(salary) > 5000; -- Text: alphabetisch erstes/letztes SELECT MIN(last_name), MAX(last_name) FROM employees; ===== Filter Funktion ===== ''HAVING'' ist eine eigene Filterklausel, die nach der Gruppierung eingesetzt wird. \\ Dabei ist es möglich, Aggregatfunktionen einzusetzen. \\ Beispiel: select manager_id, min(salary) from employees where manager_id is not NULL group by manager_id HAVING min(salary) > 6000 -- Hier werden alle Treffer mit SALARY<6000 aussortiert. order by min(SALARY) desc; ===== WICHTIG! Reihenfolge der Abarbeitung eines Querys ===== SQL-Klauseln werden in einer festgelegten **logischen Reihenfolge** abgearbeitet: FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY Damit wäre der folgende Query **falsch**: SELECT last_name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn FROM employees WHERE rn <= 10; -- ORA-00904: "RN": invalid identifier ''WHERE'' wird **vor** dem ''SELECT'' ausgewertet. Also zu dem Zeitpunkt, wo ''WHERE'' läuft, existiert der Alias ''rn'' noch gar nicht, da er erst in der ''SELECT''-Phase berechnet wird. \\ Damit der Query läuft, muss man sich als Workaround die Tatsache zu eigen machen, dass geklammerte Querys immer von innen nach außen berechnet werden. \\ Beispiel: SELECT last_name, salary FROM ( SELECT last_name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn FROM employees ) WHERE rn <= 10; **Dasselbe Problem gilt übrigens auch für** ''ORDER BY'' — auch da kann man berechnete Spalten aus dem ''SELECT'' normalerweise nicht in ''WHERE'' referenzieren, aber in ''ORDER BY'' schon (das ist eine spezielle Ausnahme des Standards). [[opendocks:oracle-sql-nutshell-doku:nutshell-doku-02|Zurück]] - [[opendocks:oracle-sql-nutshell-doku:nutshell-doku-04|Weiter]]