Katkat

Compute a Rolling Seven-Day Revenue Sum with Missing Dates

AmazonData Scientist · Technical Screen

Last updated

Tests the ability to write a PostgreSQL query that generates a continuous daily time series per seller, handles missing sales dates, filters by order status, and computes a rolling 7-day revenue sum.

Problem Statement

You are working on Amazon's Marketplace Analytics team. The team wants to monitor seller revenue trajectories by tracking daily sales and a rolling 7-day revenue sum for each seller.

You are provided with an orders table:

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    seller_id VARCHAR(50) NOT NULL,
    order_timestamp TIMESTAMPTZ NOT NULL,
    order_status VARCHAR(20) NOT NULL,
    order_amount NUMERIC(10, 2) NOT NULL
);

Write a PostgreSQL query that calculates the daily revenue and rolling 7-day revenue for each seller under the following rules:

  1. Status filter: Include only orders where order_status = 'completed'.
  2. Time zone: Truncate all timestamps to the UTC calendar date (order_date).
  3. Continuous date spine: For each seller, generate a complete daily sequence of dates starting from the date of their first completed order up to the date of their last completed order (inclusive). If a seller had no completed orders on a given date, output 0.00 for daily_revenue.
  4. Rolling 7-day window: Compute rolling_7d_revenue as the sum of daily_revenue for the current date and the preceding 6 calendar days. If fewer than 6 preceding days exist in the seller's history, sum all available days up to that point.
  5. Format & Ordering: Round both daily_revenue and rolling_7d_revenue to 2 decimal places. Sort the output by seller_id ASC, order_date ASC.

Example

Input: orders

order_idseller_idorder_timestamporder_statusorder_amount
1S12024-03-01 10:15:00+00completed100.00
2S12024-03-01 14:00:00+00cancelled50.00
3S12024-03-03 09:30:00+00completed200.00
4S12024-03-04 18:00:00+00completed50.00

Output

seller_idorder_datedaily_revenuerolling_7d_revenue
S12024-03-01100.00100.00
S12024-03-020.00100.00
S12024-03-03200.00300.00
S12024-03-0450.00350.00

Explanation: 2024-03-02 had no completed orders, so daily_revenue is 0.00. The rolling 7-day sum on 2024-03-04 covers March 1 through March 4 (100.00 + 0.00 + 200.00 + 50.00 = 350.00).

Hints

Hint 1

First aggregate completed orders by `seller_id` and UTC date, determining each seller's minimum and maximum sale dates.

Hint 2

Use PostgreSQL's `generate_series` inside a lateral join or cross-joined calendar spine to construct every date between each seller's min and max date.

Hint 3

Once the date sequence is fully populated with zero-filled gaps, use the window frame `ROWS BETWEEN 6 PRECEDING AND CURRENT ROW` to calculate the rolling 7-day sum.

Follow-up questions

  • How would you modify the query if the observation window must extend to `CURRENT_DATE` for all sellers rather than each seller's last sale date?
  • If the table contains hundreds of millions of rows across millions of sellers, what indexes would you create, and how might you optimize the calendar-spine generation?
  • How does the behavior of `ROWS BETWEEN 6 PRECEDING AND CURRENT ROW` differ from `RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW` if dates are missing?