ROWS BETWEEN
Legt den Fensterrahmen fest: die Zeilen der Partition, aus denen die Fensterfunktion den Wert für die aktuelle Zeile berechnet.
{ROWS | RANGE | GROUPS} BETWEEN frame_start AND frame_end [frame_exclusion]- [ ]optionaler Teil
- { a | b }eine der Optionen
- ROWS | RANGE | GROUPS
- Einheit der Grenzen: Zeilen, ORDER BY-Werte oder Gruppen gleicher ZeilenSchlüsselwortROWSRANGEGROUPS
- frame_start
- Anfang des RahmensSchlüsselwortUNBOUNDED PRECEDINGoffset PRECEDINGCURRENT ROWoffset FOLLOWING
- frame_end
- Ende des Rahmens, nicht vor seinem AnfangSchlüsselwortoffset PRECEDINGCURRENT ROWoffset FOLLOWINGUNBOUNDED FOLLOWING
- frame_exclusion
- Welche Zeilen aus dem Rahmen ausgeschlossen werden, standardmäßig keineSchlüsselwortOptionalEXCLUDE CURRENT ROWEXCLUDE GROUPEXCLUDE TIESEXCLUDE NO OTHERS
Rückgabewert
Gibt keinen Wert zurück: legt die Zeilen für die Fensterfunktion in OVER (...) fest
Beispiele
Summe der letzten drei Zahlungen
SELECT payment_id,
date,
unit_price,
SUM(unit_price) OVER (
ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS last_three
FROM Payments
ORDER BY date;Laufende Summe je Familienmitglied
SELECT family_member,
date,
unit_price,
SUM(unit_price) OVER (
PARTITION BY family_member
ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM Payments
ORDER BY family_member,
date;Summe der letzten 30 Tage
SELECT date,
unit_price,
SUM(unit_price) OVER (
ORDER BY date RANGE BETWEEN INTERVAL '30 days' PRECEDING
AND CURRENT ROW
) AS last_30_days
FROM Payments
ORDER BY date;ROWS, RANGE und GROUPS bei gleichen Preisen
SELECT unit_price,
COUNT(*) OVER (
ORDER BY unit_price ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS rows_frame,
COUNT(*) OVER (
ORDER BY unit_price RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS range_frame,
COUNT(*) OVER (
ORDER BY unit_price GROUPS BETWEEN 1 PRECEDING AND CURRENT ROW
) AS groups_frame
FROM Payments
ORDER BY unit_price;Details
Grenzen: UNBOUNDED PRECEDING ist der Anfang der Partition, offset PRECEDING liegt offset Zeilen vor der aktuellen, CURRENT ROW ist die aktuelle Zeile, offset FOLLOWING liegt offset Zeilen danach und UNBOUNDED FOLLOWING ist das Ende der Partition. Bei RANGE gibst du den Versatz in Einheiten von ORDER BY an, zum Beispiel INTERVAL '30 days' für Datumswerte.
Ist kein Rahmen angegeben, reicht er mit ORDER BY vom Anfang der Partition bis zur aktuellen Zeile samt allen Zeilen mit demselben ORDER BY-Wert (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), ohne ORDER BY ist es die ganze Partition. Deshalb liefern LAST_VALUE und NTH_VALUE ohne expliziten Rahmen oft etwas Unerwartetes.
EXCLUDE CURRENT ROW nimmt die aktuelle Zeile aus dem Rahmen, EXCLUDE GROUP sie und die Zeilen mit demselben ORDER BY-Wert, EXCLUDE TIES nur diese gleichen Zeilen. Auf Rangfunktionen, LAG und LEAD wirkt der Rahmen nicht.