Conversion funnel: per-step rates in one query
Count the distinct users at each step with FILTER, then unfold the funnel into rows via LATERAL VALUES to compute both the overall rate and the step-by-step rate.
Prerequisites
PostgreSQL 9.4+ (FILTER, LATERAL)
SQL
WITH steps AS (
SELECT
COUNT(DISTINCT user_id) FILTER (WHERE event = 'view_product') AS s1,
COUNT(DISTINCT user_id) FILTER (WHERE event = 'add_to_cart') AS s2,
COUNT(DISTINCT user_id) FILTER (WHERE event = 'checkout') AS s3,
COUNT(DISTINCT user_id) FILTER (WHERE event = 'payment_ok') AS s4
FROM events
WHERE event_time >= CURRENT_DATE - 7
)
SELECT
v.step,
v.users,
ROUND(100.0 * v.users / FIRST_VALUE(v.users) OVER w, 1) AS pct_total,
ROUND(100.0 * v.users / NULLIF(LAG(v.users) OVER w, 0), 1) AS pct_prev
FROM steps s
CROSS JOIN LATERAL (VALUES
(1, 'Vue produit', s.s1), (2, 'Ajout panier', s.s2),
(3, 'Checkout', s.s3), (4, 'Paiement', s.s4)
) AS v(ord, step, users)
WINDOW w AS (ORDER BY v.ord)
ORDER BY v.ord;Result
step | users | pct_total | pct_prev --------------+-------+-----------+---------- Vue produit | 48210 | 100.0 | Ajout panier | 12480 | 25.9 | 25.9 Checkout | 6840 | 14.2 | 54.8 Paiement | 5210 | 10.8 | 76.2 (4 rows)
SQLFunnelConversionProduct analytics