cswork / libraryOpen practice workspace

Coding questions · Boston Consulting Group

Query top spenders and 7-day growth

This question evaluates proficiency in SQL data manipulation, including aggregations, date-range filtering, joins, window functions for ranking and tie-breaking, and computing revenue shares and growth rates within a relational schema.

Assume 'today' = 2025-09-01. Write a SQL query to: (1) for each model, compute total revenue in the last 7 days (2025-08-26 to 2025-09-01 inclusive) and the previous 7 days (2025-08-19 to 2025-08-25), excluding orders with status <> 'completed'; (2) for each model, list the top 3 customers by spend in the last 7 days with their spend and their percentage share of the model’s 7-day revenue; (3) report, per model, the 7-day-over-7-day revenue growth rate: (curr - prev)/NULLIF(prev, 0). Return: model_name, curr_revenue, prev_revenue, growth_rate, customer_id, customer_name, customer_spend, customer_share_pct. Break ties for top-3 by the earliest first purchase date of the customer on that model (use the full order history).

Schema and small sample data:

models
model_id | model_name
1 | Sedan
2 | SUV
customers
customer_id | customer_name | country
101 | Alice | US
102 | Bob | US
103 | Chen | CN
orders
order_id | order_date | customer_id | model_id | qty | unit_price | status
1 | 2025-08-27 | 101 | 1 | 1 | 20000 | completed
2 | 2025-08-30 | 102 | 2 | 1 | 30000 | completed
3 | 2025-08-31 | 101 | 2 | 1 | 32000 | completed
4 | 2025-09-01 | 103 | 2 | 2 | 29000 | completed
5 | 2025-08-20 | 101 | 1 | 1 | 21000 | completed
6 | 2025-08-26 | 102 | 1 | 1 | 19000 | cancelled
7 | 2025-08-25 | 103 | 2 | 1 | 28000 | completed
8 | 2025-08-24 | 102 | 2 | 1 | 27000 | completed

Notes: revenue = qty*unit_price. Use window functions for ranking, partitioning by model, and tie-breaking by first purchase date.

Top 3 customers per model with 7-day revenue and growth

Assume today is 2025-06-01.

Write a SQL query to:

  1. For each model, compute total revenue in the last 7 days (2025-05-26 to 2025-06-01 inclusive) and in the previous 7 days (2025-05-19 to 2025-05-25 inclusive), excluding orders whose status is not 'completed'. Revenue is defined as qty * unit_price.

  2. For each model, list the top 3 customers by spend in the last 7 days (2025-05-26 to 2025-06-01), along with:

    • their total spend on that model in that 7-day window, and
    • their percentage share of the model’s 7-day revenue (customer_spend / model_7_day_revenue * 100).
  3. Report, per model, the 7-day-over-7-day revenue growth rate, defined as: (curr_revenue - prev_revenue) / NULLIF(prev_revenue, 0).

Return the following columns:

  • model_name
  • curr_revenue (revenue from 2025-05-26 to 2025-06-01, completed orders only)
  • prev_revenue (revenue from 2025-05-19 to 2025-05-25, completed orders only)
  • growth_rate (as defined above)
  • customer_id
  • customer_name
  • customer_spend (customer's spend on that model in the last 7 days)
  • customer_share_pct (percentage share of the model's 7-day revenue)

If a model has fewer than 3 customers with spend in the last 7 days, return only the available customers. Break ties for the top-3 ranking by the earliest first purchase date of the customer on that model using the full order history (all dates), and if still tied, by customer_id.

Use window functions for ranking (partitioning by model) and for implementing the tie-breaker logic.

Table models

columntypeconstraints
model_idINTPRIMARY KEY, NOT NULL
model_nameVARCHAR(50)NOT NULL

Sample data:

model_idmodel_name
1Sedan
2SUV

Table customers

columntypeconstraints
customer_idINTPRIMARY KEY, NOT NULL
customer_nameVARCHAR(100)NOT NULL
countryVARCHAR(50)NOT NULL

Sample data:

countrycustomer_idcustomer_name
US101Alice
US102Bob
CN103Chen

Table orders

columntypeconstraints
order_idINTPRIMARY KEY, NOT NULL
order_dateDATENOT NULL
customer_idINTNOT NULL
model_idINTNOT NULL
qtyINTNOT NULL
unit_priceDECIMAL(10,2)NOT NULL
statusVARCHAR(20)NOT NULL

Sample data:

customer_idmodel_idorder_dateorder_idqtystatusunit_price
10112025-05-2711completed20000
10222025-05-3021completed30000
10122025-05-3131completed32000
10322025-06-0142completed29000
10112025-05-2051completed21000
10212025-05-2661cancelled19000
10322025-05-2571completed28000
10222025-05-2481completed27000

Expected output

One row per model per top customer (up to 3 customers per model) for the last 7-day window (2025-05-26 to 2025-06-01). Each row includes the model's current-/previous-7-day revenue, growth rate, and the customer's spend and share of the model's current 7-day revenue.

curr_revenuecustomer_idcustomer_namecustomer_share_pctcustomer_spendgrowth_ratemodel_nameprev_revenue
20000.00101Alice10020000.00-0.0476Sedan21000.00
120000.00103Chen48.333358000.001.1818SUV55000.00
120000.00101Alice26.666732000.001.1818SUV55000.00
120000.00102Bob2530000.001.1818SUV55000.00

Hints

  1. First aggregate per model to get revenue in each 7-day window, using CASE expressions in a GROUP BY.
  2. Then aggregate per (model, customer) for the last 7 days, compute each customer's first purchase date per model, and use ROW_NUMBER with an ORDER BY that applies the tie-breaker to select the top 3 customers per model.