You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询需求:构建客户IVR/Email退订状态报表

解决方案:生成客户退订状态报表

这是一个典型的行转列报表需求,我给你两种实用的实现方案,优先推荐第一种,因为效率更高且代码更简洁:

方案1:条件聚合 + LEFT JOIN(推荐)

通过一次关联+聚合函数,直接生成所需的列格式,完美适配你的需求:

SELECT
    c.id AS customer_id,
    c.name,
    -- 判断是否有IVR渠道退订,无则显示No
    COALESCE(MAX(CASE WHEN o.notification_channel = 'IVR' THEN 'Yes' END), 'No') AS `IVR Optout`,
    -- 判断是否有EMAIL渠道退订,无则显示No
    COALESCE(MAX(CASE WHEN o.notification_channel = 'EMAIL' THEN 'Yes' END), 'No') AS `Email Optout`
FROM tt_customers c
-- LEFT JOIN确保所有客户都被包含,哪怕没有退订记录
LEFT JOIN tt_opt_outs o ON c.id = o.customer_id
-- 按客户分组,聚合每个客户的退订状态
GROUP BY c.id, c.name;

逻辑说明:

  • LEFT JOIN:保证所有tt_customers里的客户都会出现在结果中,不受退订记录存在与否的影响
  • CASE WHEN:针对每条退订记录判断渠道,匹配时返回Yes
  • MAX():聚合函数会保留该客户对应渠道的Yes(只要有至少一条退订记录就会显示Yes)
  • COALESCE():把无退订记录时的NULL转换成No,让报表更直观
  • 全程未过滤event_type,自动忽略其对退订状态的影响

方案2:子查询关联(适合新手理解)

如果觉得聚合函数逻辑有点绕,可以用子查询分别筛选出两种渠道的退订客户,再关联到客户表:

SELECT
    c.id AS customer_id,
    c.name,
    CASE WHEN ivr.customer_id IS NOT NULL THEN 'Yes' ELSE 'No' END AS `IVR Optout`,
    CASE WHEN email.customer_id IS NOT NULL THEN 'Yes' ELSE 'No' END AS `Email Optout`
FROM tt_customers c
-- 关联有IVR退订的客户(去重避免重复行)
LEFT JOIN (SELECT DISTINCT customer_id FROM tt_opt_outs WHERE notification_channel = 'IVR') ivr
    ON c.id = ivr.customer_id
-- 关联有EMAIL退订的客户(去重避免重复行)
LEFT JOIN (SELECT DISTINCT customer_id FROM tt_opt_outs WHERE notification_channel = 'EMAIL') email
    ON c.id = email.customer_id;

逻辑说明:

  • 子查询先筛选出对应渠道的退订客户ID,用DISTINCT去重,避免关联后产生重复行
  • 通过LEFT JOIN关联到客户表,判断子查询结果是否为NULL来标记退订状态
  • 同样忽略了event_type,符合需求

内容的提问来源于stack exchange,提问作者wubbalubba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:49:09