====== 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]]