111 lines
4.3 KiB
SQL
111 lines
4.3 KiB
SQL
-- 近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;
|