ai_member_xiaoxi/scripts/welfare_query.sql
2026-05-20 08:00:01 +08:00

139 lines
4.7 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 福利品用户筛选拥有两个年包课包level1或level2各算一个年包
-- goods_id: 31=level2/年包, 60=level1, 61=level1+2(算两个年包)
WITH
-- 目标订单(仅已完成/已退款,剔除测试账号)
target_orders AS (
SELECT
o.account_id,
o.trade_no,
o.goods_id,
o.goods_name,
o.key_from,
o.pay_success_date,
o.pay_amount_int,
o.order_status
FROM vala_bi.bi_vala_order o
JOIN vala_bi.bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
WHERE o.goods_id IN (31, 60, 61)
AND o.order_status IN (3, 4)
AND o.pay_success_date IS NOT NULL
),
-- 退费信息(仅退费成功)
refund_info AS (
SELECT
trade_no,
refund_amount_int
FROM vala_bi.bi_refund_order
WHERE status = 3
),
-- 订单 + 退费标记
order_with_refund AS (
SELECT
t.*,
r.refund_amount_int AS refund_amt,
CASE
WHEN r.refund_amount_int IS NULL THEN 'none'
WHEN r.refund_amount_int < t.pay_amount_int THEN 'partial'
ELSE 'full'
END AS refund_type
FROM target_orders t
LEFT JOIN refund_info r ON t.trade_no = r.trade_no
),
-- ===== 情况1: goods_id=61, 无任何退费 =====
case1_users AS (
SELECT DISTINCT account_id
FROM order_with_refund
WHERE goods_id = 61 AND refund_type = 'none'
),
-- ===== 情况2: goods_id IN (31,60), >=2笔有效订单, 最多一笔400元部分退费 =====
case2_eligible AS (
SELECT
account_id,
COUNT(*) AS total_valid,
SUM(CASE WHEN refund_type = 'none' THEN 1 ELSE 0 END) AS no_refund_cnt,
SUM(CASE WHEN refund_type = 'partial' AND refund_amt = 40000 THEN 1 ELSE 0 END) AS partial_400_cnt,
SUM(CASE WHEN refund_type = 'full' THEN 1 ELSE 0 END) AS full_refund_cnt,
SUM(CASE WHEN refund_type = 'partial' AND refund_amt != 40000 THEN 1 ELSE 0 END) AS other_partial_cnt
FROM order_with_refund
WHERE goods_id IN (31, 60)
AND refund_type != 'full' -- 排除全额退款
GROUP BY account_id
HAVING COUNT(*) >= 2
AND SUM(CASE WHEN refund_type = 'partial' AND refund_amt = 40000 THEN 1 ELSE 0 END) <= 1
AND SUM(CASE WHEN refund_type = 'partial' AND refund_amt != 40000 THEN 1 ELSE 0 END) = 0
),
-- 排除全额退款的无效订单后的明细
case2_valid_orders AS (
SELECT *
FROM order_with_refund
WHERE goods_id IN (31, 60) AND refund_type != 'full'
),
case2_users AS (
SELECT DISTINCT account_id FROM case2_eligible
),
-- ===== 情况3: goods_id IN (31,60) 至少一笔无退费 + goods_id=61 一笔退费1999 =====
case3_has_31_60 AS (
SELECT DISTINCT account_id
FROM order_with_refund
WHERE goods_id IN (31, 60) AND refund_type = 'none'
),
case3_has_61_1999 AS (
SELECT DISTINCT account_id
FROM order_with_refund
WHERE goods_id = 61 AND refund_type = 'partial' AND refund_amt = 199900
),
case3_users AS (
SELECT a.account_id
FROM case3_has_31_60 a
JOIN case3_has_61_1999 b ON a.account_id = b.account_id
),
-- ===== 合并所有符合条件的用户 =====
all_eligible_users AS (
SELECT account_id FROM case1_users
UNION
SELECT account_id FROM case2_users
UNION
SELECT account_id FROM case3_users
)
-- ===== 最终输出:符合条件的用户 + 其所有相关订单 + parent_address =====
SELECT
ou.account_id::text AS "用户ID",
r.trade_no AS "交易号",
r.goods_id AS "商品ID",
r.goods_name AS "商品名称",
r.key_from AS "渠道",
r.pay_success_date AS "购课日期",
r.pay_amount_int / 100.0 AS "支付金额(元)",
r.refund_amt / 100.0 AS "退款金额(元)",
r.refund_type AS "退费状态",
pa.name AS "收件人",
pa.phone_number AS "电话",
pa.region AS "区域",
pa.address AS "地址",
CASE
WHEN ou.account_id IN (SELECT account_id FROM case1_users) THEN '情况1'
WHEN ou.account_id IN (SELECT account_id FROM case2_users) THEN '情况2'
WHEN ou.account_id IN (SELECT account_id FROM case3_users) THEN '情况3'
END AS "来源情况"
FROM all_eligible_users ou
JOIN (
-- 输出情况1的订单
SELECT * FROM order_with_refund WHERE goods_id = 61 AND refund_type = 'none' AND account_id IN (SELECT account_id FROM case1_users)
UNION ALL
-- 输出情况2的订单仅有效订单
SELECT * FROM case2_valid_orders WHERE account_id IN (SELECT account_id FROM case2_users)
UNION ALL
-- 输出情况3的订单包含31/60无退费 + 61退费1999
SELECT * FROM order_with_refund
WHERE (goods_id IN (31, 60) AND refund_type = 'none' AND account_id IN (SELECT account_id FROM case3_users))
OR (goods_id = 61 AND refund_type = 'partial' AND refund_amt = 199900 AND account_id IN (SELECT account_id FROM case3_users))
) r ON ou.account_id = r.account_id
LEFT JOIN vala_class.parent_address pa ON ou.account_id::text = pa.account_id
ORDER BY ou.account_id, r.goods_id, r.trade_no;