# Forum Post Detail Funnel SQL This project now stores tracking events in table `forum_track_events`. Daily rollup is also available in `forum_track_daily_summary`. Key columns: - `event_name` - `label` - `post_id` - `user_id` - `visitor_id` - `cta_variant` - `created_at` Use the queries below as baseline funnel cuts. ## 1) Daily impression -> pricing CTA conversion (MySQL) ```sql SELECT DATE(created_at) AS d, COALESCE(cta_variant, 'unknown') AS cta_variant, COUNT(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 END) AS impressions, COUNT(CASE WHEN event_name = 'post_detail_cta_pricing' THEN 1 END) AS pricing_clicks, ROUND( COUNT(CASE WHEN event_name = 'post_detail_cta_pricing' THEN 1 END) * 100.0 / NULLIF(COUNT(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 END), 0), 2 ) AS ctr_pct FROM forum_track_events WHERE created_at >= NOW() - INTERVAL 30 DAY GROUP BY DATE(created_at), COALESCE(cta_variant, 'unknown') ORDER BY d DESC, cta_variant; ``` ## 2) Unique visitor funnel by variant (MySQL) ```sql WITH pv AS ( SELECT COALESCE(NULLIF(visitor_id, ''), CONCAT('u:', user_id)) AS actor_id, COALESCE(cta_variant, 'unknown') AS cta_variant, MAX(event_name = 'post_detail_cta_impression') AS seen_impression, MAX(event_name = 'post_detail_cta_pricing') AS clicked_pricing, MAX(event_name = 'post_detail_comment_submit') AS submitted_comment FROM forum_track_events WHERE created_at >= NOW() - INTERVAL 30 DAY GROUP BY COALESCE(NULLIF(visitor_id, ''), CONCAT('u:', user_id)), COALESCE(cta_variant, 'unknown') ) SELECT cta_variant, COUNT(*) AS actors, SUM(seen_impression) AS actors_with_impression, SUM(clicked_pricing) AS actors_with_pricing_click, SUM(submitted_comment) AS actors_with_comment, ROUND(SUM(clicked_pricing) * 100.0 / NULLIF(SUM(seen_impression), 0), 2) AS actor_ctr_pct, ROUND(SUM(submitted_comment) * 100.0 / NULLIF(SUM(seen_impression), 0), 2) AS actor_comment_rate_pct FROM pv GROUP BY cta_variant ORDER BY cta_variant; ``` ## 3) Top performing CTA labels (MySQL) ```sql SELECT label, COUNT(*) AS clicks FROM forum_track_events WHERE event_name IN ('post_detail_cta_pricing', 'post_detail_cta_new_topic', 'post_detail_sidebar_compare') AND created_at >= NOW() - INTERVAL 30 DAY GROUP BY label ORDER BY clicks DESC LIMIT 20; ``` ## 4) Daily impression -> pricing CTA conversion (SQLite) ```sql SELECT DATE(created_at) AS d, COALESCE(cta_variant, 'unknown') AS cta_variant, SUM(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 ELSE 0 END) AS impressions, SUM(CASE WHEN event_name = 'post_detail_cta_pricing' THEN 1 ELSE 0 END) AS pricing_clicks, ROUND( SUM(CASE WHEN event_name = 'post_detail_cta_pricing' THEN 1 ELSE 0 END) * 100.0 / NULLIF(SUM(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 ELSE 0 END), 0), 2 ) AS ctr_pct FROM forum_track_events WHERE created_at >= DATETIME('now', '-30 days') GROUP BY DATE(created_at), COALESCE(cta_variant, 'unknown') ORDER BY d DESC, cta_variant; ``` ## 5) Post-level conversion ranking (SQLite/MySQL compatible style) ```sql SELECT post_id, COALESCE(cta_variant, 'unknown') AS cta_variant, SUM(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 ELSE 0 END) AS impressions, SUM(CASE WHEN event_name = 'post_detail_cta_pricing' THEN 1 ELSE 0 END) AS pricing_clicks, ROUND( SUM(CASE WHEN event_name = 'post_detail_cta_pricing' THEN 1 ELSE 0 END) * 100.0 / NULLIF(SUM(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 ELSE 0 END), 0), 2 ) AS ctr_pct FROM forum_track_events WHERE post_id IS NOT NULL GROUP BY post_id, COALESCE(cta_variant, 'unknown') HAVING impressions >= 20 ORDER BY ctr_pct DESC, impressions DESC LIMIT 50; ``` ## 6) Daily rollup table quick check (SQLite/MySQL compatible style) ```sql SELECT event_day, cta_variant, event_name, total FROM forum_track_daily_summary WHERE event_day >= DATE('now', '-30 day') -- MySQL: CURDATE() - INTERVAL 30 DAY ORDER BY event_day DESC, cta_variant, event_name; ``` ## 7) Mobile sticky-bar exposure rate (SQLite/MySQL compatible style) ```sql SELECT DATE(created_at) AS d, COALESCE(cta_variant, 'unknown') AS cta_variant, SUM(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 ELSE 0 END) AS impressions, SUM(CASE WHEN event_name = 'post_detail_mobile_bar_impression' THEN 1 ELSE 0 END) AS mobile_bar_impressions, ROUND( SUM(CASE WHEN event_name = 'post_detail_mobile_bar_impression' THEN 1 ELSE 0 END) * 100.0 / NULLIF(SUM(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 ELSE 0 END), 0), 2 ) AS mobile_bar_exposure_pct FROM forum_track_events WHERE created_at >= DATETIME('now', '-30 days') GROUP BY DATE(created_at), COALESCE(cta_variant, 'unknown') ORDER BY d DESC, cta_variant; ``` ## 8) Device split performance (SQLite/MySQL compatible style) ```sql SELECT DATE(created_at) AS d, COALESCE(device_type, 'unknown') AS device_type, COALESCE(cta_variant, 'unknown') AS cta_variant, SUM(CASE WHEN event_name = 'post_detail_cta_impression' THEN 1 ELSE 0 END) AS impressions, SUM(CASE WHEN event_name = 'post_detail_mobile_bar_impression' THEN 1 ELSE 0 END) AS mobile_bar_impressions, SUM(CASE WHEN event_name = 'post_detail_cta_pricing' THEN 1 ELSE 0 END) AS pricing_clicks, SUM(CASE WHEN event_name = 'post_detail_cta_pricing' AND label LIKE 'mobile_%' THEN 1 ELSE 0 END) AS mobile_pricing_clicks FROM forum_track_events WHERE created_at >= DATETIME('now', '-30 days') GROUP BY DATE(created_at), COALESCE(device_type, 'unknown'), COALESCE(cta_variant, 'unknown') ORDER BY d DESC, device_type, cta_variant; ```