Fensterfunktion (SQL)Eine Fensterfunktion (englisch Window Function) in SQL ist eine analytische Funktion[1], die Werte aus einem oder mehreren Tupeln verwendet, um einen Wert pro Tupel zurückzugeben. (Dies steht im Gegensatz zu einer Aggregatfunktion, die einen einzigen Wert für mehrere Tupel zurückgibt.) Fensterfunktionen haben eine OVER-Klausel; jede Funktion ohne OVER-Klausel ist keine Fensterfunktion, sondern eine Aggregat- oder einzeilige (skalare) Funktion.[2] Als Beispiel ist hier eine Anfrage angegeben, die eine Fensterfunktion verwendet, um das Gehalt jedes Mitarbeiters mit dem Durchschnittsgehalt seiner Abteilung zu vergleichen (Beispiel aus der PostgreSQL-Dokumentation):[3] SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
Ausgabe: depname | empno | salary | avg ----------+-------+--------+---------------------- develop | 11 | 5200 | 5020.0000000000000000 develop | 7 | 4200 | 5020.0000000000000000 develop | 9 | 4500 | 5020.0000000000000000 develop | 8 | 6000 | 5020.0000000000000000 develop | 10 | 5200 | 5020.0000000000000000 personnel | 5 | 3500 | 3700.0000000000000000 personnel | 2 | 3900 | 3700.0000000000000000 sales | 3 | 4800 | 4866.6666666666666667 sales | 1 | 5000 | 4866.6666666666666667 sales | 4 | 4800 | 4866.6666666666666667 (10 rows) Die PARTITION BY-Klausel gruppiert Tupel in Partitionen, innerhalb derer die Funktion angewendet wird. Fehlt die PARTITION BY-Klausel (z. B. bei einer leeren OVER()-Klausel), wird die gesamte Ergebnismenge als eine einzige Partition behandelt. Bei dieser Abfrage wäre das angegebene Durchschnittsgehalt der Durchschnitt über alle Zeilen. Fensterfunktionen werden nach der Aggregation ausgewertet, also nach der GROUP BY-Klausel mit zugehörigen Aggregatfunktionen.[4] SyntaxLaut der PostgreSQL-Dokumentation hat eine Window-Funktion die folgende Syntax:[5] function_name ([expression [, expression ... ]]) OVER window_name
function_name ([expression [, expression ... ]]) OVER ( window_definition )
function_name ( * ) OVER window_name
function_name ( * ) OVER ( window_definition )
wobei [ existing_window_name ]
[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ frame_clause ]
{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ]
{ RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ]
BeispielFensterfunktionen ermöglichen den Zugriff auf Daten direkt vor und nach dem aktuellen Tupel.[6][7][8][9] Eine Fensterfunktion definiert ein Fenster (engl.: Window) von Tupeln mit einer bestimmten Anzahl vor und nach der aktuellen Zeile und führt eine Berechnung über den Tupeln im jeweils gültigen Fenster durch.[10][11] NAME | ------------ Aaron| <-- Preceding (unbounded) Andrew| Amelia| James| Jill| Johnny| <-- 1st preceding row Michael| <-- Current row Nick| <-- 1st following row Ophelia| Zach| <-- Following (unbounded) Die nachfolgende Anfrage extrahiert für jedes Tupel in der obigen Tabelle die Werte einer vorangehenden und einer nachfolgenden Zeile: SELECT
LAG(name, 1)
OVER(ORDER BY name) "prev",
name,
LEAD(name, 1)
OVER(ORDER BY name) "next"
FROM people
ORDER BY name
Das Ergebnis enthält die folgenden Werte: | PREV | NAME | NEXT | |----------|----------|----------| | (null)| Aaron| Andrew| | Aaron| Andrew| Amelia| | Andrew| Amelia| James| | Amelia| James| Jill| | James| Jill| Johnny| | Jill| Johnny| Michael| | Johnny| Michael| Nick| | Michael| Nick| Ophelia| | Nick| Ophelia| Zach| | Ophelia| Zach| (null)| GeschichteFensterfunktionen wurden in SQL:2003 eingeführt und deren Funktionalität in späteren Spezifikationen erweitert.[12] Einzelnachweise
|