MySQL如何实现列转行并计算各列总和输出指定格式结果
MySQL实现列聚合结果行转列
你需要实现的是将多列的聚合求和结果转换为「列名-聚合值」的行式输出,本质是对宽表做逆透视聚合,Excel中可以通过透视表/逆透视快速实现,MySQL中可以通过以下两种方案实现:
固定列场景:UNION ALL 直接实现
如果需要统计的列是固定的,这是最简单、性能最好、无版本兼容问题的方案。
针对你给出的A/B/C三列测试表,写法如下:
SELECT 'A' AS `Columns`, CONCAT('sum(A) = ', SUM(A)) AS `Values` FROM 你的表名 UNION ALL SELECT 'B' AS `Columns`, CONCAT('sum(B) = ', SUM(B)) AS `Values` FROM 你的表名 UNION ALL SELECT 'C' AS `Columns`, CONCAT('sum(C) = ', SUM(C)) AS `Values` FROM 你的表名;
执行后就能得到你要的输出格式:
| Columns | Values |
|---|---|
| A | sum(A) = 6 |
| B | sum(B) = 15 |
| C | sum(C) = 24 |
针对你业务中的fantasydefensegame表,要统计Sacks、SacksYards、PointsAllowed三个字段的和,写法如下:
SELECT 'Sacks' AS `Columns`, SUM(Sacks) AS `Values` FROM fantasydefensegame UNION ALL SELECT 'SacksYards' AS `Columns`, SUM(SacksYards) AS `Values` FROM fantasydefensegame UNION ALL SELECT 'PointsAllowed' AS `Columns`, SUM(PointsAllowed) AS `Values` FROM fantasydefensegame;
如果需要按SeasonType字段分组统计,所有子查询都要加上分组字段和分组逻辑即可:
SELECT SeasonType, 'Sacks' AS `Columns`, SUM(Sacks) AS `Values` FROM fantasydefensegame GROUP BY SeasonType UNION ALL SELECT SeasonType, 'SacksYards' AS `Columns`, SUM(SacksYards) AS `Values` FROM fantasydefensegame GROUP BY SeasonType UNION ALL SELECT SeasonType, 'PointsAllowed' AS `Columns`, SUM(PointsAllowed) AS `Values` FROM fantasydefensegame GROUP BY SeasonType;
注意:
UNION会对结果做去重操作,性能差还可能因为聚合值相同丢失数据,这类场景统一用UNION ALL即可,要求每个子查询返回的列数、列类型完全一致,否则会报语法错误。
动态列场景:预处理语句动态生成SQL
如果需要统计的列不固定,不想每次修改SQL文本,可以通过预处理语句动态拼接查询逻辑,你之前写的动态SQL存在单引号转义错误、拼接逻辑错误,修正后写法如下:
-- 初始化存储SQL的变量 SET @sql = NULL; -- 从系统表读取字段信息,拼接UNION ALL子句 SELECT GROUP_CONCAT( 'SELECT ''', COLUMN_NAME, ''' AS `Columns`, SUM(`', COLUMN_NAME, '`) AS `Values` FROM 你的表名' SEPARATOR ' UNION ALL ' ) INTO @sql FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() -- 匹配当前数据库 AND TABLE_NAME = '你的表名' -- 替换为实际表名 AND COLUMN_NAME IN ('A','B','C'); -- 指定需要统计的列,不写则统计该表所有列 -- 执行拼接完成的SQL PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
你之前尝试的写法存在的问题
- 部分UNION子查询返回的列数和其他子查询不一致,会触发列数不匹配错误
- 动态SQL拼接时,字符串内部的单引号没有做转义(字符串里的单引号需要写两个单引号表示转义),导致语法解析失败
- 混用UNION和UNION ALL,存在不必要的去重性能损耗
内容的提问来源于stack exchange,提问作者Sunny Sunny
相关产品推荐
相关产品推荐

