Interview question
Calculate seven-day rolling revenue
Combines daily aggregation, a calendar table, and a window frame to calculate true seven-calendar-day revenue.
TL;DR
Combines daily aggregation, a calendar table, and a window frame to calculate true seven-calendar-day revenue.
Daily grain, missing-date handling, window frames, date boundaries, and report correctness.
Practice the problem like a real interview: restate, reason, implement, and test.
Tables: Orders(OrderId, PaidAtUtc, Status, TotalAmount) and CalendarDates(DateValue), containing one row per date. Return each date from @FromDate through @ThroughDate, its paid revenue, and revenue for that date plus the previous six calendar dates.
Next in Query Practice: Latest Order Status
If Monday has 10 revenue, Tuesday has no orders, and Wednesday has 30, the daily rows are 10, 0, and 30. Wednesday's rolling value includes all three dates and equals 40.
@FromDate so the first displayed rolling value has full history.I first aggregate orders to daily grain. Then I join those totals onto a complete calendar series so a ROWS frame really means seven consecutive calendar days rather than seven dates that happened to contain orders. I calculate the window over the expanded range and filter display dates only after the window value exists.
WITH RevenueByDay AS
(
SELECT
CONVERT(date, o.PaidAtUtc) AS RevenueDate,
SUM(o.TotalAmount) AS DailyRevenue
FROM dbo.Orders AS o
WHERE o.Status = 'Paid'
AND o.PaidAtUtc >= DATEADD(day, -6, CONVERT(datetime2, @FromDate))
AND o.PaidAtUtc < DATEADD(day, 1, CONVERT(datetime2, @ThroughDate))
GROUP BY CONVERT(date, o.PaidAtUtc)
),
Series AS
(
SELECT
c.DateValue,
COALESCE(r.DailyRevenue, CONVERT(decimal(18, 2), 0)) AS DailyRevenue
FROM dbo.CalendarDates AS c
LEFT JOIN RevenueByDay AS r ON r.RevenueDate = c.DateValue
WHERE c.DateValue >= DATEADD(day, -6, @FromDate)
AND c.DateValue <= @ThroughDate
),
Rolling AS
(
SELECT
DateValue,
DailyRevenue,
SUM(DailyRevenue) OVER
(
ORDER BY DateValue
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS RollingSevenDayRevenue
FROM Series
)
SELECT DateValue, DailyRevenue, RollingSevenDayRevenue
FROM Rolling
WHERE DateValue >= @FromDate
ORDER BY DateValue;
The expensive step is the initial order aggregation over the expanded date range. A filtered or covering index for paid orders can help, while a persisted daily summary makes repeated dashboard reads much cheaper. The window runs over a small date series rather than raw order rows.
@FromDate before calculating the rolling value.Spot a weak answer, missing edge case, or clearer explanation? Send it in.