0
0
SQLquery~20 mins

Moving averages with window frames in SQL - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Master of Moving Averages
Get all challenges correct to earn this badge!
Test your skills under time pressure!
query_result
intermediate
2:00remaining
Calculate 3-day moving average using ROWS frame
Given a sales table with columns sale_date and amount, what is the output of this query?

SELECT sale_date, amount, 
       AVG(amount) OVER (ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM sales
ORDER BY sale_date;
SQL
CREATE TABLE sales (sale_date DATE, amount INT);
INSERT INTO sales VALUES
('2024-01-01', 100),
('2024-01-02', 200),
('2024-01-03', 300),
('2024-01-04', 400),
('2024-01-05', 500);
A[{"sale_date": "2024-01-01", "amount": 100, "moving_avg": 100.0}, {"sale_date": "2024-01-02", "amount": 200, "moving_avg": 150.0}, {"sale_date": "2024-01-03", "amount": 300, "moving_avg": 200.0}, {"sale_date": "2024-01-04", "amount": 400, "moving_avg": 300.0}, {"sale_date": "2024-01-05", "amount": 500, "moving_avg": 400.0}]
B[{"sale_date": "2024-01-01", "amount": 100, "moving_avg": 100.0}, {"sale_date": "2024-01-02", "amount": 200, "moving_avg": 200.0}, {"sale_date": "2024-01-03", "amount": 300, "moving_avg": 300.0}, {"sale_date": "2024-01-04", "amount": 400, "moving_avg": 400.0}, {"sale_date": "2024-01-05", "amount": 500, "moving_avg": 500.0}]
C[{"sale_date": "2024-01-01", "amount": 100, "moving_avg": 100.0}, {"sale_date": "2024-01-02", "amount": 200, "moving_avg": 150.0}, {"sale_date": "2024-01-03", "amount": 300, "moving_avg": 300.0}, {"sale_date": "2024-01-04", "amount": 400, "moving_avg": 400.0}, {"sale_date": "2024-01-05", "amount": 500, "moving_avg": 500.0}]
D[{"sale_date": "2024-01-01", "amount": 100, "moving_avg": null}, {"sale_date": "2024-01-02", "amount": 200, "moving_avg": null}, {"sale_date": "2024-01-03", "amount": 300, "moving_avg": 200.0}, {"sale_date": "2024-01-04", "amount": 400, "moving_avg": 300.0}, {"sale_date": "2024-01-05", "amount": 500, "moving_avg": 400.0}]
Attempts:
2 left
💡 Hint
Think about how ROWS BETWEEN 2 PRECEDING AND CURRENT ROW includes the current row and two before it.
query_result
intermediate
2:00remaining
Calculate 3-day moving average using RANGE frame
Given the same sales table, what is the output of this query?

SELECT sale_date, amount, 
       AVG(amount) OVER (ORDER BY sale_date RANGE BETWEEN INTERVAL '2' DAY PRECEDING AND CURRENT ROW) AS moving_avg
FROM sales
ORDER BY sale_date;
SQL
CREATE TABLE sales (sale_date DATE, amount INT);
INSERT INTO sales VALUES
('2024-01-01', 100),
('2024-01-02', 200),
('2024-01-03', 300),
('2024-01-04', 400),
('2024-01-05', 500);
A[{"sale_date": "2024-01-01", "amount": 100, "moving_avg": null}, {"sale_date": "2024-01-02", "amount": 200, "moving_avg": null}, {"sale_date": "2024-01-03", "amount": 300, "moving_avg": 200.0}, {"sale_date": "2024-01-04", "amount": 400, "moving_avg": 300.0}, {"sale_date": "2024-01-05", "amount": 500, "moving_avg": 400.0}]
B[{"sale_date": "2024-01-01", "amount": 100, "moving_avg": 150.0}, {"sale_date": "2024-01-02", "amount": 200, "moving_avg": 150.0}, {"sale_date": "2024-01-03", "amount": 300, "moving_avg": 300.0}, {"sale_date": "2024-01-04", "amount": 400, "moving_avg": 400.0}, {"sale_date": "2024-01-05", "amount": 500, "moving_avg": 500.0}]
C[{"sale_date": "2024-01-01", "amount": 100, "moving_avg": 100.0}, {"sale_date": "2024-01-02", "amount": 200, "moving_avg": 200.0}, {"sale_date": "2024-01-03", "amount": 300, "moving_avg": 300.0}, {"sale_date": "2024-01-04", "amount": 400, "moving_avg": 400.0}, {"sale_date": "2024-01-05", "amount": 500, "moving_avg": 500.0}]
D[{"sale_date": "2024-01-01", "amount": 100, "moving_avg": 100.0}, {"sale_date": "2024-01-02", "amount": 200, "moving_avg": 150.0}, {"sale_date": "2024-01-03", "amount": 300, "moving_avg": 200.0}, {"sale_date": "2024-01-04", "amount": 400, "moving_avg": 300.0}, {"sale_date": "2024-01-05", "amount": 500, "moving_avg": 400.0}]
Attempts:
2 left
💡 Hint
RANGE frame includes rows within 2 days before the current sale_date.
📝 Syntax
advanced
1:30remaining
Identify the syntax error in window frame clause
Which option contains a syntax error in the window frame clause of this query?

SELECT sale_date, amount, 
       AVG(amount) OVER (ORDER BY sale_date ROWS BETWEEN CURRENT ROW AND 2 PRECEDING) AS moving_avg
FROM sales;
AROWS BETWEEN 2 PRECEDING AND CURRENT ROW
BROWS BETWEEN CURRENT ROW AND 2 PRECEDING
CROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
DROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
Attempts:
2 left
💡 Hint
The frame must start with a lower boundary and end with a higher boundary.
optimization
advanced
2:00remaining
Optimize moving average calculation for large dataset
You have a large sales table with millions of rows. Which approach is most efficient to calculate a 7-day moving average of amount ordered by sale_date?
AUse AVG(amount) OVER (ORDER BY sale_date RANGE BETWEEN INTERVAL '6' DAY PRECEDING AND CURRENT ROW)
BUse AVG(amount) OVER (ORDER BY sale_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)
CUse a correlated subquery to calculate average for each row
DUse a self join on sale_date between current date and 6 days before and aggregate
Attempts:
2 left
💡 Hint
Consider how the data is distributed and the type of frame that matches date intervals.
🧠 Conceptual
expert
2:30remaining
Understanding difference between ROWS and RANGE frames
Which statement correctly explains the difference between ROWS and RANGE window frames in moving average calculations?
AROWS frame can only be used with numeric ORDER BY; RANGE frame only with date ORDER BY.
BROWS frame includes all rows with values within a specified range; RANGE frame counts physical rows before the current row.
CROWS frame counts physical rows before the current row; RANGE frame includes all rows with values within a specified range of the ORDER BY expression.
DROWS and RANGE frames behave identically when ORDER BY is on a numeric column.
Attempts:
2 left
💡 Hint
Think about how each frame defines the window based on position vs value.