RANGE is used inside the OVER() clause of a window function to specify how many rows are visible to that function when calculating its result. Unlike ROWS, which counts a fixed number of physical rows, RANGE groups together all rows that have ORDER BY values falling within the same logical interval around the current row. Standard SQL supports UNBOUNDED PRECEDING, CURRENT ROW, numeric or interval offsets, and UNBOUNDED FOLLOWING as frame boundaries. A RANGE frame is always inclusive and requires an ORDER BY clause that contains exactly one expression (or multiple expressions that together form a unique ordering in dialects that allow it). If the ORDER BY column is numeric, a numeric offset is allowed; if it is date or time based, an INTERVAL literal is required. RANGE is evaluated after PARTITION BY filtering but before the window function itself executes. It is case-insensitive, but best practice is to write it in upper case for readability. Some databases also use RANGE in table partitioning (PARTITION BY RANGE) or generated columns, but those contexts represent separate grammar rules.
frame_start
(boundary) - Marks the first row included in the frameframe_end
(boundary) - Marks the last row included in the framen
(integer / interval) - Offset applied to the ORDER BY value (numerical or INTERVAL)ROWS, GROUPS, OVER, WINDOW, PARTITION BY, ORDER BY, PARTITION BY RANGE (table partitioning)
SQL:2003 window function specification
RANGE uses logical value equality on the ORDER BY expression, so all tied rows are processed together. ROWS counts a physical offset regardless of ties.
No. RANGE requires an ORDER BY expression to measure logical distance between rows.
Numeric ORDER BY columns accept integer offsets (e.g., 3 PRECEDING). Date or timestamp columns must use INTERVAL literals (e.g., INTERVAL '7 day' PRECEDING).
If multiple rows share the same ORDER BY value, RANGE includes every one of them, which can enlarge the frame beyond a simple row count.