IntermediateAdvanced PostgreSQL
Window function frame modes: ROWS vs RANGE
The query
SQL
-- ROWS: physical rows
SELECT
order_date::DATE,
total,
SUM(total) OVER (
ORDER BY order_date::DATE
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS rows_3day_sum,
-- RANGE: logical range (all rows with same ORDER BY value)
SUM(total) OVER (
ORDER BY order_date::DATE
RANGE BETWEEN INTERVAL '2 days' PRECEDING AND CURRENT ROW
) AS range_3day_sum,
-- GROUPS: frame by peer groups (PostgreSQL 11+)
SUM(total) OVER (
ORDER BY order_date::DATE
GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS groups_3day_sum
FROM orders
WHERE status = 'completed'
ORDER BY order_date;Note
“ROWS = exact row count. RANGE = value-based (ties included). GROUPS = distinct values. Different results for ties!