Investigation plan (high level)1. Verify data pipeline & time ranges (no late-arriving or duplicated rows).2. Reproduce the 12% MoM drop in total revenue and by key dimensions (cohort, channel, user segments).3. Drill down: AOV, number of buyers, refunds, new vs returning users, channel mix, retention curves.4. Form hypotheses (pricing change, acquisition mix, lower retention, increased refunds) and test with slices.5. Summarize findings and recommend next steps (fix data/bugs, pricing experiments, acquisition reallocation, retention campaign).SQL: total revenue and confirm dropsql
-- Monthly revenue
SELECT date_trunc('month', purchase_date) AS month,
SUM(amount) AS revenue,
COUNT(DISTINCT user_id) AS buyers,
AVG(amount) AS aov
FROM purchases
GROUP BY 1
ORDER BY 1 DESC;
Revenue by acquisition cohort (signup month)sql
-- Cohort revenue by purchase month
SELECT cohort, purchase_month,
SUM(amount) AS revenue,
COUNT(DISTINCT p.user_id) AS buyers
FROM (
SELECT user_id, date_trunc('month', signup_date) AS cohort, channel FROM users
) u
JOIN purchases p ON u.user_id = p.user_id
CROSS JOIN LATERAL (SELECT date_trunc('month', p.purchase_date) AS purchase_month)
GROUP BY 1,2
ORDER BY 1,2;
Revenue by acquisition channel (current vs prior month)sql
SELECT date_trunc('month', p.purchase_date) AS month,
u.channel,
SUM(p.amount) AS revenue,
COUNT(DISTINCT p.user_id) AS buyers,
AVG(p.amount) AS aov
FROM purchases p
JOIN users u ON p.user_id = u.user_id
GROUP BY 1,2
ORDER BY 1 DESC, 3 DESC;
Revenue-per-user distribution (for recent month)sql
SELECT user_id, SUM(amount) AS spend
FROM purchases
WHERE purchase_date >= date_trunc('month', current_date - interval '1 month')
AND purchase_date < date_trunc('month', current_date)
GROUP BY 1;
-- then compute percentiles
SELECT
percentile_cont(0.5) WITHIN GROUP (ORDER BY spend) AS median,
percentile_cont(0.9) WITHIN GROUP (ORDER BY spend) AS p90,
percentile_cont(0.99) WITHIN GROUP (ORDER BY spend) AS p99
FROM (
-- subquery above
) t;
Refunds analysissql
-- Refunds vs purchases by month
SELECT date_trunc('month', p.purchase_date) AS month,
SUM(p.amount) AS gross_revenue,
COALESCE(SUM(r.amount),0) AS refunds,
SUM(p.amount) - COALESCE(SUM(r.amount),0) AS net_revenue,
COALESCE(SUM(r.amount),0) / NULLIF(SUM(p.amount),0) AS refund_rate
FROM purchases p
LEFT JOIN refunds r ON p.purchase_id = r.purchase_id
GROUP BY 1
ORDER BY 1 DESC;
Retention & repeat purchase ratesql
-- Repeat buyers in month
WITH monthly_buyers AS (
SELECT date_trunc('month', purchase_date) AS month, user_id
FROM purchases
GROUP BY 1,2
)
SELECT month,
COUNT(*) AS buyers,
COUNT(*) FILTER (WHERE user_first_purchase_month < month) AS returning_buyers,
(COUNT(*) FILTER (WHERE user_first_purchase_month < month))::float / COUNT(*) AS returning_rate
FROM (
SELECT mb.month, mb.user_id,
MIN(date_trunc('month', p.purchase_date)) OVER (PARTITION BY p.user_id) AS user_first_purchase_month
FROM monthly_buyers mb
JOIN purchases p ON mb.user_id = p.user_id
) t
GROUP BY 1
ORDER BY 1 DESC;
What patterns indicate each root cause- Pricing / AOV change: AOV falls across all channels/cohorts simultaneously; median and p90 spend drop; average basket size decreases but buyer count stable.- Acquisition mix shift: Total buyers same or up, but revenue drops because share from high-LTV channels decreased and low-LTV channels increased; new-user cohort LTV much lower; channel-level AOVs differ.- Retention issue: New and returning cohorts show lower repeat-purchase rates; cohort curves decline faster (less revenue in month+1, month+2); number of buyers declines even if AOV stable.- Refunds / chargebacks: Refund amount or refund_rate spikes in the month and explains net revenue gap; refunds concentrated in particular SKUs/channels or correlated with certain cohorts.- Data/implementation bug: Sudden drop isolated to specific data source, missing purchases table partitions, or event->purchase attribution broken (check events table for checkout completions vs purchases).Next steps / tests- Compare gross vs net revenue to quantify refund impact.- Segment by product/price-tier to detect pricing/regression.- Run statistical significance on MoM differences (buyers, AOV).- Pull raw events around checkout to detect conversion drop.- Work with finance/engineering to validate discount codes, pricing changes, and with marketing to inspect channel spend changes.