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

MySQL如何将唯一列值转为列头?求通用客户统计动态列方案

MySQL动态行转列:按活动统计各事件的用户唯一计数与总计数

针对你的需求——统计每个campaign_name下,各event_name对应的customer_id唯一计数和总记录数,且event_name数量不固定,可通过MySQL动态SQL实现通用解决方案:

1. 先理解静态逻辑(固定事件场景)

如果已知所有event_name,可以用CASE表达式配合聚合函数实现:

SELECT
    campaign_name,
    -- event_1的唯一用户数
    COUNT(DISTINCT CASE WHEN event_name = 'event_1' THEN customer_id END) AS event_1_unique_count,
    -- event_1的总记录数
    COUNT(CASE WHEN event_name = 'event_1' THEN customer_id END) AS event_1_total_count,
    -- event_2的唯一用户数
    COUNT(DISTINCT CASE WHEN event_name = 'event_2' THEN customer_id END) AS event_2_unique_count,
    -- event_2的总记录数
    COUNT(CASE WHEN event_name = 'event_2' THEN customer_id END) AS event_2_total_count
FROM event_data -- 替换成你的表名
GROUP BY campaign_name;

2. 动态SQL通用方案(适配任意数量的event_name)

由于event_name不固定,需要动态生成上述CASE语句,借助MySQL的预处理语句实现:

-- 临时调整GROUP_CONCAT的最大长度(如果事件数量多,按需设置)
SET SESSION group_concat_max_len = 1000000;

SET @sql = NULL;

-- 动态生成每个事件对应的统计列片段
SELECT
    GROUP_CONCAT(
        DISTINCT CONCAT(
            'COUNT(DISTINCT CASE WHEN event_name = ''', event_name, ''' THEN customer_id END) AS `', event_name, '_unique_count`, ',
            'COUNT(CASE WHEN event_name = ''', event_name, ''' THEN customer_id END) AS `', event_name, '_total_count`'
        )
    ) INTO @sql
FROM event_data; -- 替换成你的表名

-- 拼接完整的查询语句
SET @sql = CONCAT(
    'SELECT campaign_name, ', @sql, ' FROM event_data GROUP BY campaign_name'
);

-- 执行动态生成的SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

关键说明

  • 用GROUP_CONCAT遍历所有唯一的event_name,自动生成每个事件对应的两个统计列;
  • 列名用反引号``包裹,避免event_name包含特殊字符导致SQL语法错误;
  • 如果你的表名不是event_data,记得替换所有对应位置的表名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:17:36