SQL Practice Logo

SQLPractice Online

Window Frame Specifications: Examples

Module: Window Functions

Basic Frame Types - ROWS vs RANGE Comparison

intermediate

Understanding the fundamental difference between ROWS and RANGE frame types

-- Sample data with duplicate dates to show ROWS vs RANGE difference

WITH daily_sales AS (

SELECT * FROM VALUES

('2024-01-01'::date, 'Store A', 100),

('2024-01-01'::date, 'Store B', 150), -- Same date as above

('2024-01-02'::date, 'Store A', 200),

('2024-01-03'::date, 'Store A', 120),

('2024-01-03'::date, 'Store B', 180) -- Same date as above

AS t(sale_date, store, amount)

)

SELECT

sale_date,

store,

amount,

-- ROWS: Physical row counting (most common)

SUM(amount) OVER (

ORDER BY sale_date, store

ROWS BETWEEN 1 PRECEDING AND CURRENT ROW

) as rows_2row_sum,

-- RANGE: Logical value-based (includes ties)

SUM(amount) OVER (

ORDER BY sale_date

RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

) as range_running_sum,

-- Show the difference clearly

COUNT(*) OVER (

ORDER BY sale_date, store

ROWS BETWEEN 1 PRECEDING AND CURRENT ROW

) as rows_count,

COUNT(*) OVER (

ORDER BY sale_date

RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

) as range_count,

-- Practical example: Moving average with ROWS

ROUND(AVG(amount) OVER (

ORDER BY sale_date, store

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW