cswork / libraryOpen practice workspace

Coding questions · Meta

Compute SHOP spend share and model performance

This question evaluates proficiency in SQL/Python data manipulation and analytics, focusing on aggregations, joins, time-window computations, handling missing or zero values, and deriving key metrics such as revenue share and revenue-per-conversion.

You work on ads measurement. Advertisers can drive users to either Facebook Shop ('SHOP') or their own website ('WEBSITE'). After an ad is shown, you attribute downstream revenue and conversions to the destination.

Assume the following tables (all timestamps are in UTC and event_date is a calendar date):

Table 1: ad_revenue

  • event_date DATE
  • advertiser_id BIGINT
  • destination VARCHAR -- values: 'SHOP' or 'WEBSITE'
  • revenue_usd NUMERIC -- attributed revenue in USD

Table 2: ad_conversions

  • event_date DATE
  • advertiser_id BIGINT
  • destination VARCHAR -- values: 'SHOP' or 'WEBSITE'
  • conversions BIGINT -- attributed conversion count

Notes/assumptions

  • There is at most one row per (event_date, advertiser_id, destination) per table.
  • “Past 30 days” means the most recent 30 calendar days including the max event_date in the data.

Tasks

  1. SHOP share over past 30 days

Write SQL to compute, for each event_date in the past 30 days, the share of revenue going to destination='SHOP':

Required output columns:

  • event_date
  • shop_revenue
  • total_revenue
  • shop_revenue_share = shop_revenue / total_revenue
  1. How does the FB model perform?

Using only these two tables, write SQL to produce a stakeholder-ready daily time series for the past 30 days that helps evaluate performance by destination.

At minimum, include:

  • event_date
  • destination
  • revenue_usd
  • conversions
  • revenue_per_conversion = revenue_usd / NULLIF(conversions, 0)

Also include at least one “share”-style diagnostic (e.g., revenue share or conversion share across destinations) that could indicate whether performance is shifting toward SHOP vs WEBSITE.

State any additional assumptions you make (e.g., how to handle missing rows / zero totals).

Compute SHOP revenue share over the last 30 days

Facebook ads can lead customers to either an advertiser's in-app checkout ('SHOP') or the advertiser's external site ('WEBSITE').

Using the data in ad_revenue, compute how the share of revenue attributed to 'SHOP' performed over the last 30 days.

Assume "last 30 days" means FROM 2025-05-03 TO 2025-06-01 (inclusive).

Return one row per advertiser plus one additional roll-up row for all advertisers combined.

Output columns:

  • advertiser_id (use NULL for the all-advertisers roll-up)
  • total_revenue_usd
  • shop_revenue_usd
  • shop_revenue_share (shop_revenue_usd / total_revenue_usd, rounded to 4 decimals)

Notes:

  • Use actual_channel to determine whether revenue is SHOP vs WEBSITE.
  • Only include rows whose event_date is in the given date range.

Table ad_revenue

columntypeconstraints
impression_idBIGINTPRIMARY KEY
event_dateDATENOT NULL
advertiser_idINTNOT NULL
model_versionVARCHAR(10)NOT NULL
predicted_channelVARCHAR(10)NOT NULL
actual_channelVARCHAR(10)NOT NULL
revenue_usdDECIMAL(10,2)NOT NULL

Sample data:

actual_channeladvertiser_idevent_dateimpression_idmodel_versionpredicted_channelrevenue_usd
SHOP1012025-05-011v1SHOP100
WEBSITE1012025-05-032v1SHOP80
WEBSITE1012025-05-103v1WEBSITE120
SHOP1012025-05-204v2SHOP200
SHOP1012025-05-285v2WEBSITE60
SHOP1022025-05-056v1SHOP150
WEBSITE1022025-05-187v1SHOP50
WEBSITE1022025-05-308v2WEBSITE130
SHOP1022025-06-019v2SHOP90
SHOP1032025-05-0710v1WEBSITE70
SHOP1032025-05-2511v2SHOP110
WEBSITE1032025-05-3112v2WEBSITE160
SHOP1032025-05-1513v1SHOP40

Table ad_conversions

columntypeconstraints
impression_idBIGINTPRIMARY KEY
event_dateDATENOT NULL
conversionsINTNOT NULL

Sample data:

conversionsevent_dateimpression_id
22025-05-011
12025-05-032
22025-05-103
32025-05-204
12025-05-285
22025-05-056
12025-05-187
22025-05-308
12025-06-019
12025-05-0710
22025-05-2511
42025-05-3112
12025-05-1513

Expected output

One row per advertiser plus a roll-up row (advertiser_id = NULL) showing total revenue, SHOP revenue, and SHOP share for 2025-05-03 through 2025-06-01 inclusive.

advertiser_idshop_revenue_shareshop_revenue_usdtotal_revenue_usd
1010.5652260460
1020.5714240420
1030.5789220380
NULL0.57147201260

Hints

  1. Use conditional aggregation: SUM(CASE WHEN actual_channel='SHOP' THEN revenue_usd END).
  2. Add an overall row with UNION ALL (or GROUPING SETS if supported).

Evaluate model performance over the last 30 days

Facebook uses a model to predict whether a user should be sent to 'SHOP' or 'WEBSITE'.

Using ad_revenue and ad_conversions, evaluate model performance for the date range FROM 2025-05-03 TO 2025-06-01 (inclusive).

Define model performance as:

  • prediction_accuracy: fraction of impressions where predicted_channel = actual_channel (rounded to 4 decimals)
  • total_revenue_usd: sum of revenue_usd
  • total_conversions: sum of conversions
  • revenue_per_conversion_usd: total_revenue_usd / total_conversions (rounded to 2 decimals)

Return one row per model_version.

Table ad_revenue

columntypeconstraints
impression_idBIGINTPRIMARY KEY
event_dateDATENOT NULL
advertiser_idINTNOT NULL
model_versionVARCHAR(10)NOT NULL
predicted_channelVARCHAR(10)NOT NULL
actual_channelVARCHAR(10)NOT NULL
revenue_usdDECIMAL(10,2)NOT NULL

Sample data:

actual_channeladvertiser_idevent_dateimpression_idmodel_versionpredicted_channelrevenue_usd
SHOP1012025-05-011v1SHOP100
WEBSITE1012025-05-032v1SHOP80
WEBSITE1012025-05-103v1WEBSITE120
SHOP1012025-05-204v2SHOP200
SHOP1012025-05-285v2WEBSITE60
SHOP1022025-05-056v1SHOP150
WEBSITE1022025-05-187v1SHOP50
WEBSITE1022025-05-308v2WEBSITE130
SHOP1022025-06-019v2SHOP90
SHOP1032025-05-0710v1WEBSITE70
SHOP1032025-05-2511v2SHOP110
WEBSITE1032025-05-3112v2WEBSITE160
SHOP1032025-05-1513v1SHOP40

Table ad_conversions

columntypeconstraints
impression_idBIGINTPRIMARY KEY
event_dateDATENOT NULL
conversionsINTNOT NULL

Sample data:

conversionsevent_dateimpression_id
22025-05-011
12025-05-032
22025-05-103
32025-05-204
12025-05-285
22025-05-056
12025-05-187
22025-05-308
12025-06-019
12025-05-0710
22025-05-2511
42025-05-3112
12025-05-1513

Expected output

One row per model_version with accuracy (predicted_channel vs actual_channel), total revenue, total conversions, and revenue per conversion for 2025-05-03 through 2025-06-01 inclusive.

model_versionprediction_accuracyrevenue_per_conversion_usdtotal_conversionstotal_revenue_usd
v10.563.758510
v20.833357.6913750

Hints

  1. Accuracy can be computed as AVG of a 0/1 indicator for correct predictions.
  2. Join revenue to conversions on impression_id, and filter by the explicit date range.