Using Window Frame Clauses

1. Understanding Frame Boundaries

ModeUnit
ROWSPhysical rows
RANGELogical (by ORDER BY value)
GROUPSPeer groups PG 11+

2. Using UNBOUNDED PRECEDING

SELECT day, sum(revenue) OVER (ORDER BY day
       ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
  FROM daily_revenue;

3. Using UNBOUNDED FOLLOWING

SELECT day, sum(revenue) OVER (ORDER BY day
       ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS remaining_total
  FROM daily_revenue;

4. Using CURRENT ROW

ModeCURRENT ROW Means
ROWSThis row only
RANGEAll rows with same ORDER BY value
GROUPSAll rows in same peer group

5. Using n PRECEDING

SELECT day, avg(revenue) OVER (ORDER BY day
       ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma7
  FROM daily_revenue;

6. Using n FOLLOWING

SELECT day, avg(revenue) OVER (ORDER BY day
       ROWS BETWEEN 0 PRECEDING AND 6 FOLLOWING) AS forward_avg
  FROM daily_revenue;

7. Using ROWS BETWEEN

... OVER (ORDER BY t ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING)

8. Using RANGE BETWEEN

SELECT ts, sum(amt) OVER (
   ORDER BY ts
   RANGE BETWEEN INTERVAL '1 hour' PRECEDING AND CURRENT ROW
) AS amount_last_hour
  FROM tx;
RANGE RequiresDetail
Single ORDER BY columnNumeric or date/time
Offset typeCompatible with ORDER BY column

9. Using GROUPS BETWEEN

SELECT name, score,
       avg(score) OVER (ORDER BY score
                        GROUPS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS neighbor_avg
  FROM players;

10. Using EXCLUDE Clause

OptionRemoves
EXCLUDE CURRENT ROWThe row itself
EXCLUDE GROUPEntire peer group
EXCLUDE TIESPeers but keep current row
EXCLUDE NO OTHERSDefault

11. Using CUME_DIST and PERCENT_RANK Functions

SELECT name, score,
       cume_dist()    OVER (ORDER BY score) AS cdist,
       percent_rank() OVER (ORDER BY score) AS prank
  FROM players;
FunctionFormula
cume_dist()(rows ≤ current) / total
percent_rank()(rank - 1) / (total - 1)