SQL · medium · Asked at Amazon
Asked in Data Analyst interviews, in the SQL round.
Use SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW).
A rolling window over an ordered daily series. Aggregate to the day first, then apply the window; the frame is the part people get wrong.
WITH daily AS (
SELECT order_date, SUM(amount) AS revenue
FROM orders
GROUP BY order_date
)
SELECT
order_date,
revenue,
SUM(revenue) OVER (
ORDER BY order_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS revenue_7d
FROM daily
ORDER BY order_date;
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW is the current row plus the six before it: seven rows. But rows are not days. If a date has no orders, there is no row for it, and the window quietly reaches back eight or nine calendar days. The honest version joins to a date spine first so every day exists (with 0 revenue), or uses RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW, which Postgres supports for date ordering.