Date Operations & Time-Based Analytics SQL Topic exerciseMediumVerified answerSQLite + MySQL + SQL Server live · 2 guided

Calculate Year-To-Date (YTD) Sales by Month

Aggregate 2024 sales by month and calculate the cumulative YTD sales within the year.

  • Window functions
  • Aggregation
  • Date analysis
  • Type conversion
  • Filtering

Exercise brief

Understand the request

Finance analytics lead The 2024 management pack needs monthly revenue and a year-to-date running total.

The 2024 management pack needs monthly revenue and a year-to-date running total. Aggregate 2024 sales by month and calculate the cumulative YTD sales within the year.

Return

  • Return year, month, monthly_sales, ytd_sales in this exact left-to-right order.

Constraints

  • Aggregate to month grain before applying the running total.
  • Partition the window by calendar year.
  • Order chronologically.

Data you will use

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

orders

  • order_idINTEGER
  • order_dateDATE
  • order_totalDECIMAL

Hints, when you need them

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

Hint 1

YTD = running total of monthly sales, reset each year (PARTITION BY year).

Hint 2

SUM(SUM(order_total)) OVER (...) is a window function applied on top of the GROUP BY aggregate.

Hint 3

PARTITION BY year ensures the running total restarts on January.

Verified SQL answer

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

Reveal solution and explanation
SELECT CAST(strftime('%Y', order_date) AS INTEGER) AS year, CAST(strftime('%m', order_date) AS INTEGER) AS month, SUM(order_total) AS monthly_sales, SUM(SUM(order_total)) OVER (PARTITION BY strftime('%Y', order_date) ORDER BY strftime('%m', order_date) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS ytd_sales FROM orders WHERE strftime('%Y', order_date) = '2024' GROUP BY strftime('%Y', order_date), strftime('%m', order_date) ORDER BY year, month;

Why this works

YTD combines aggregation (monthly SUM) with a window function (running SUM of those monthlies). The nested SUM(SUM(...)) OVER is legal because the inner SUM is the group aggregate and the outer SUM is the window. PARTITION BY year resets the accumulation at each year boundary. Only the date-extraction differs across engines.

Success check

Each 2024 month appears once and the final YTD value equals total 2024 revenue.

Expected result

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

yearmonthmonthly_salesytd_sales
20241430430
20242470900
202437001600
202445402140
202456002740
202467003440
202473303770
202482704040
202494504490
2024103104800

Previewing 10 of 12 expected rows. Run the query in the editor to inspect the full result.

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.