Window frame (ROWS BETWEEN, RANGE BETWEEN) in PostgreSQL - Time & Space Complexity
When using window frames like ROWS BETWEEN or RANGE BETWEEN in SQL, it is important to understand how the query's work grows as the data size increases.
We want to know how the number of rows processed affects the time it takes to compute the window functions.
Analyze the time complexity of the following PostgreSQL query using a window frame.
SELECT employee_id, department_id, salary,
AVG(salary) OVER (
PARTITION BY department_id
ORDER BY employee_id
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS avg_salary
FROM employees;
This query calculates the average salary for each employee considering the current row and the two previous rows within the same department.
Look for repeated work done for each row in the window frame.
- Primary operation: Calculating the average over a sliding window of up to 3 rows per employee.
- How many times: For each row, the database processes up to 3 rows to compute the average.
As the number of rows grows, the work per row depends on the window frame size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 x 3 = 30 operations |
| 100 | About 100 x 3 = 300 operations |
| 1000 | About 1000 x 3 = 3000 operations |
Pattern observation: The total work grows roughly in a straight line with the number of rows, multiplied by the fixed window size.
Time Complexity: O(n)
This means the time to compute the window function grows linearly with the number of rows, assuming the window frame size is fixed.
[X] Wrong: "The window frame always causes the query to do work on all rows for each row, so it's quadratic."
[OK] Correct: When the window frame size is fixed (like 2 preceding rows), the database only looks at a small, constant number of rows per row, so the work grows linearly, not quadratically.
Understanding how window frames affect query performance helps you write efficient SQL and explain your reasoning clearly in interviews.
What if we changed the window frame from ROWS BETWEEN 2 PRECEDING AND CURRENT ROW to RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW? How would the time complexity change?
Practice
ROWS BETWEEN clause specify in a window function?Solution
Step 1: Understand window frame types
Window frames can be defined by position (ROWS) or by value range (RANGE).Step 2: Identify what ROWS BETWEEN does
ROWS BETWEEN counts rows relative to the current row's position, not by values.Final Answer:
It defines the frame by counting rows relative to the current row position. -> Option AQuick Check:
ROWS BETWEEN = position-based frame [OK]
- Confusing ROWS with RANGE
- Thinking ROWS filters rows
- Assuming ROWS sorts data
RANGE BETWEEN from 5 preceding to current row?Solution
Step 1: Recall RANGE BETWEEN syntax
The syntax is: RANGE BETWEEN <start> AND <end>, where start must be before end logically.Step 2: Check order of frame boundaries
5 PRECEDING comes before CURRENT ROW, so 'RANGE BETWEEN 5 PRECEDING AND CURRENT ROW' is correct.Final Answer:
RANGE BETWEEN 5 PRECEDING AND CURRENT ROW -> Option AQuick Check:
Correct RANGE syntax = RANGE BETWEEN 5 PRECEDING AND CURRENT ROW [OK]
- Reversing frame boundaries order
- Using ROWS syntax with RANGE
- Omitting BETWEEN keyword
sales(date, amount) ordered by date, what will the following query return?SELECT date, amount, SUM(amount) OVER (ORDER BY date RANGE BETWEEN INTERVAL '1 day' PRECEDING AND CURRENT ROW) AS running_sum FROM sales;
Solution
Step 1: Understand RANGE BETWEEN with INTERVAL
RANGE BETWEEN INTERVAL '1 day' PRECEDING AND CURRENT ROW includes rows with date values within 1 day before current row's date.Step 2: Interpret the SUM window function
SUM(amount) will add amounts for rows dated from 1 day before up to current date.Final Answer:
Sum of amounts for the current date and the previous day -> Option CQuick Check:
RANGE with INTERVAL sums by date range [OK]
- Confusing RANGE with ROWS counting
- Assuming ROWS behavior for RANGE
- Ignoring INTERVAL meaning
SUM(amount) OVER (ORDER BY date ROWS BETWEEN CURRENT ROW AND 3 PRECEDING)
Solution
Step 1: Check frame boundary order
Frame boundaries must go from earlier to later, so '3 PRECEDING' should be before 'CURRENT ROW'.Step 2: Validate syntax correctness
Using ROWS with ORDER BY date and SUM is valid, so no other syntax errors.Final Answer:
The frame boundaries are reversed; '3 PRECEDING' should come before 'CURRENT ROW'. -> Option DQuick Check:
Frame boundaries order matters [OK]
- Reversing frame boundaries
- Thinking ROWS can't use ORDER BY
- Misunderstanding window function usage
sales table has multiple sales per day. Which window frame clause correctly computes this using RANGE?Solution
Step 1: Understand the requirement
We want a 7-day moving average including current day, so the frame covers 6 days before plus current day (total 7 days).Step 2: Choose correct frame type
Since multiple sales per day exist, using RANGE with INTERVAL ensures all rows within date range are included.Step 3: Select correct interval
INTERVAL '6 days' PRECEDING to CURRENT ROW covers 7 days total (6 before + current).Final Answer:
RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW -> Option BQuick Check:
Use RANGE with 6 days preceding for 7-day window [OK]
- Using ROWS which counts rows, not days
- Choosing wrong interval length
- Confusing 6 days preceding with 7 days
Ready to prove it?
Pass the test and this pattern moves unknown
