Date Operations & Time-Based Analytics SQL Topic exerciseHardVerified answerSQLite + PostgreSQL + MySQL + SQL Server live · 1 guided

Build a Dense 7-Calendar-Day Moving Average

Build daily revenue for every date in calendar_days and calculate a seven-calendar-day moving average.

  • Window functions
  • Joins
  • Subqueries
  • Aggregation
  • Date analysis

Exercise brief

Understand the request

Revenue analytics engineer A seven-calendar-day trend must retain dates with no activity instead of collapsing to seven observed rows.

A seven-calendar-day trend must retain dates with no activity instead of collapsing to seven observed rows. Build daily revenue for every date in calendar_days and calculate a seven-calendar-day moving average.

Return

  • Return calendar_date, daily_revenue, and rolling_avg_7_calendar_days.
  • Order by calendar_date.

Constraints

  • LEFT JOIN activity to the calendar table.
  • Convert missing or all-NULL daily revenue to zero before windowing.
  • Use ROWS BETWEEN 6 PRECEDING AND CURRENT ROW and order by calendar_date.

Data you will use

Review the relevant tables before deciding how to join, filter, or aggregate them.

calendar_days

  • calendar_dateDATE

daily_activity

  • activity_idINTEGER
  • activity_dateDATE
  • revenueDECIMAL

Hints, when you need them

Open one clue at a time so you still do the reasoning.

Hint 1

Begin from calendar_days so dates without activity survive.

Hint 2

Aggregate after a LEFT JOIN and COALESCE the daily SUM to zero.

Hint 3

Window the dense daily rows with the current row and six preceding rows.

Verified SQL answer

Attempt the problem first, then compare structure and reasoning—not just syntax.

Reveal solution and explanation
WITH daily AS (SELECT c.calendar_date, COALESCE(SUM(a.revenue), 0) AS daily_revenue FROM calendar_days c LEFT JOIN daily_activity a ON a.activity_date = c.calendar_date GROUP BY c.calendar_date) SELECT calendar_date, daily_revenue, ROUND(AVG(daily_revenue) OVER (ORDER BY calendar_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW), 2) AS rolling_avg_7_calendar_days FROM daily ORDER BY calendar_date;

Why this works

A ROWS frame counts rows, not elapsed time. A calendar spine makes one row equal one calendar day, turning a seven-row frame into a truthful seven-calendar-day metric.

Success check

All ten calendar dates appear, zero-activity dates contribute zero, and each mature window spans exactly seven consecutive calendar rows.

Expected result

Use this output to verify values, aliases, ordering, and row count.

calendar_datedaily_revenuerolling_avg_7_calendar_days
2025-01-01100100
2025-01-027587.5
2025-01-03058.33
2025-01-04043.75
2025-01-0520075
2025-01-06062.5
2025-01-077063.57
2025-01-08049.29
2025-01-09038.57
2025-01-104044.29

Learn the concepts behind this answer

Strengthen your understanding with these targeted learning topics:

Continue practicing

SQL Practice Online

Open the interactive workspace and practice across SQL topics.