-- 近14天(2026-05-09 ~ 2026-05-22)没有完课行为的付费用户占比 -- [李承龙确认] 口径定义见 MEMORY.md "近14天无完课行为付费用户占比" WITH paying_users AS ( -- 付费用户:pay_success_date IS NOT NULL AND order_status = 3(已完成,不含退费) -- 关联 bi_vala_app_account 剔除测试账号(status ≠ 1) SELECT DISTINCT o.account_id FROM bi_vala_order o JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1 WHERE o.pay_success_date IS NOT NULL AND o.order_status = 3 ), paying_user_goods AS ( -- 每个付费用户的 goods_id 汇总 SELECT o.account_id, array_agg(DISTINCT o.goods_id) AS goods_ids FROM bi_vala_order o JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1 WHERE o.pay_success_date IS NOT NULL AND o.order_status = 3 GROUP BY o.account_id ), user_level AS ( -- 判定 L1/L2 等级 SELECT account_id, CASE -- L1+L2 商品 WHEN 61 = ANY(goods_ids) THEN 'L1+L2' -- 同时有 L1 和 L2 商品 WHEN (57 = ANY(goods_ids) OR 60 = ANY(goods_ids) OR 63 = ANY(goods_ids)) AND (31 = ANY(goods_ids) OR 32 = ANY(goods_ids) OR 33 = ANY(goods_ids) OR 54 = ANY(goods_ids)) THEN 'L1+L2' -- 仅 L1 WHEN (57 = ANY(goods_ids) OR 60 = ANY(goods_ids) OR 63 = ANY(goods_ids)) THEN '仅L1' -- 仅 L2 WHEN (31 = ANY(goods_ids) OR 32 = ANY(goods_ids) OR 33 = ANY(goods_ids) OR 54 = ANY(goods_ids)) THEN '仅L2' ELSE '其他' END AS level FROM paying_user_goods ), done_users AS ( -- 近14天有完课行为的 user_id(8张分表 UNION) SELECT DISTINCT user_id FROM ( SELECT user_id FROM bi_user_chapter_play_record_0 WHERE play_status = 1 AND created_at >= '2026-05-09' AND created_at < '2026-05-23' UNION SELECT user_id FROM bi_user_chapter_play_record_1 WHERE play_status = 1 AND created_at >= '2026-05-09' AND created_at < '2026-05-23' UNION SELECT user_id FROM bi_user_chapter_play_record_2 WHERE play_status = 1 AND created_at >= '2026-05-09' AND created_at < '2026-05-23' UNION SELECT user_id FROM bi_user_chapter_play_record_3 WHERE play_status = 1 AND created_at >= '2026-05-09' AND created_at < '2026-05-23' UNION SELECT user_id FROM bi_user_chapter_play_record_4 WHERE play_status = 1 AND created_at >= '2026-05-09' AND created_at < '2026-05-23' UNION SELECT user_id FROM bi_user_chapter_play_record_5 WHERE play_status = 1 AND created_at >= '2026-05-09' AND created_at < '2026-05-23' UNION SELECT user_id FROM bi_user_chapter_play_record_6 WHERE play_status = 1 AND created_at >= '2026-05-09' AND created_at < '2026-05-23' UNION SELECT user_id FROM bi_user_chapter_play_record_7 WHERE play_status = 1 AND created_at >= '2026-05-09' AND created_at < '2026-05-23' ) t ), paying_user_done_status AS ( -- 付费用户是否有完课行为(通过 character 关联 user_id) -- MAX: 只要用户有任意一个角色在近14天有完课,就算有完课行为 SELECT ul.account_id, ul.level, MAX(CASE WHEN du.user_id IS NOT NULL THEN 1 ELSE 0 END) AS has_done FROM user_level ul LEFT JOIN bi_vala_app_character c ON ul.account_id = c.account_id LEFT JOIN done_users du ON c.id = du.user_id GROUP BY ul.account_id, ul.level ) -- 按 level 分组统计 SELECT level, COUNT(DISTINCT account_id) AS total_paying, COUNT(DISTINCT CASE WHEN has_done = 0 THEN account_id END) AS no_done_paying, ROUND( COUNT(DISTINCT CASE WHEN has_done = 0 THEN account_id END)::numeric / COUNT(DISTINCT account_id)::numeric * 100, 1 ) AS no_done_pct FROM paying_user_done_status GROUP BY level UNION ALL -- 总计行 SELECT '合计' AS level, COUNT(DISTINCT account_id) AS total_paying, COUNT(DISTINCT CASE WHEN has_done = 0 THEN account_id END) AS no_done_paying, ROUND( COUNT(DISTINCT CASE WHEN has_done = 0 THEN account_id END)::numeric / COUNT(DISTINCT account_id)::numeric * 100, 1 ) AS no_done_pct FROM paying_user_done_status ORDER BY level;