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_endParameter
- ROWS | RANGE | GROUPSSchlüsselwort
- Wie die Grenzen gezählt werden: ROWS in Zeilen, RANGE nach dem Wert in ORDER BY, GROUPS in Gruppen von Zeilen mit gleichem ORDER BY-Wert
- Werte:ROWSRANGEGROUPS
- frame_startSchlüsselwort
- Anfang des Rahmens
- Werte:UNBOUNDED PRECEDINGoffset PRECEDINGCURRENT ROWoffset FOLLOWING
- frame_endSchlüsselwort
- Ende des Rahmens, nicht vor seinem Anfang
- Werte:offset PRECEDINGCURRENT ROWoffset FOLLOWINGUNBOUNDED FOLLOWING
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.
Nach dem Rahmen kannst du Zeilen ausschließen: EXCLUDE CURRENT ROW, EXCLUDE GROUP oder EXCLUDE TIES. Auf Rangfunktionen, LAG und LEAD wirkt der Rahmen nicht.