Approach summary- Problem: web_events are hourly (event-level) and sales_by_day is daily revenue only — no purchase timestamps or order counts. Pragmatic plan: (A) derive daily visits from web_events, (B) derive daily purchases (or estimate counts) from sales_by_day, (C) compute conversion = purchases / visits with a 2-hour attribution window assumption and surface uncertainty/confidence.Assumptions (state these to stakeholders)- “Visit” = event_type IN ('view','page_view','product_page') and we count unique users per product within day.- 2-hour attribution: a visit converts if a purchase happens within 2 hours after that visit.- sales_by_day has only revenue; we either have product_price table to convert revenue→count, or we estimate purchases = revenue / avg_order_value(product).- If an orders table exists, use it instead (preferred).SQL/pseudocode steps1) Visits per hour/day per product (unique users)sql
WITH visits AS (
SELECT
DATE(hour_ts) AS day,
product_id,
COUNT(DISTINCT user_id) AS unique_visitors
FROM web_events
WHERE event_type IN ('view','product_page')
GROUP BY 1,2
)
2) If orders table available, get purchase events with timestamps:sql
, purchases AS (
SELECT
DATE(purchase_ts) AS day,
product_id,
COUNT(DISTINCT order_id) AS purchases
FROM orders
WHERE purchase_ts >= <start>
GROUP BY 1,2
)
If no orders table, derive purchases from revenue:sql
, purchases_est AS (
SELECT
day,
product_id,
ROUND(total_revenue / NULLIF(avg_price,0)) AS purchases_est
FROM sales_by_day s
JOIN product_price p USING(product_id) -- or precomputed avg_price
)
3) Compute conversion by product/day:sql
SELECT
v.day,
v.product_id,
COALESCE(p.purchases, p_est.purchases_est) AS purchases,
v.unique_visitors AS visits,
SAFE_DIVIDE(COALESCE(p.purchases, p_est.purchases_est), NULLIF(v.unique_visitors,0)) AS conversion_rate
FROM visits v
LEFT JOIN purchases p
ON v.day = p.day AND v.product_id = p.product_id
LEFT JOIN purchases_est p_est
ON v.day = p_est.day AND v.product_id = p_est.product_id;
4) (Optional) 2-hour attribution sensitivity: if you have order timestamps and visit timestamps, join visits to purchases where purchase_ts BETWEEN visit_ts AND visit_ts + INTERVAL '2' HOUR and count unique visits that led to purchase. If only daily granularity, note this is an approximation.Flagging uncertainty for stakeholders- Explicitly label rows as "estimated" when purchases come from revenue/avg_price rather than orders.- Provide confidence metrics: % of conversions based on actual orders vs estimated, coverage of web events (missing user_id?), and sensitivity analysis (recompute conversion with 1h, 2h, 4h windows and show variance).- Show top assumptions in a short doc: how visits defined, how AOV computed, timezone handling, bot filtering.- Recommend next steps to improve accuracy: join to orders table, capture purchase timestamps, instrument session IDs, or store purchase counts in daily sales.Why this is pragmatic- Uses available data first, falls back to reasonable estimation, surfaces uncertainty so stakeholders understand limits, and provides concrete next steps to reduce ambiguity.