MySQL如何将表列值转为SELECT列名并统计对应类型费用
把类型名称转为列名并统计对应费用的SQL实现
静态场景(已知所有类型名称)
如果types表的类型是固定的(比如你提到的wood、metal、steel),用条件聚合就能直接实现需求:
SELECT l.id, SUM(CASE WHEN t.name = 'wood' THEN l.cost ELSE 0 END) AS wood, SUM(CASE WHEN t.name = 'metal' THEN l.cost ELSE 0 END) AS metal, SUM(CASE WHEN t.name = 'steel' THEN l.cost ELSE 0 END) AS steel FROM lines l INNER JOIN types t ON l.type_id = t.id GROUP BY l.id;
核心逻辑:
- 通过
INNER JOIN关联两张表,匹配每条费用记录对应的类型名称 - 用
CASE表达式筛选对应类型的费用,再用SUM累加同一id下的该类型总费用 - 最终按
lines.id分组,得到每个id对应的各类型费用总和
动态场景(类型名称不固定/会新增)
如果types表的类型是动态变化的,没法提前写死列名,就得用动态SQL生成查询语句(以下以MySQL为例):
-- 拼接动态列的SQL片段 SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'SUM(CASE WHEN t.name = ''', name, ''' THEN l.cost ELSE 0 END) AS `', name, '`' ) ) INTO @sql FROM types; -- 组合成完整的查询语句 SET @sql = CONCAT('SELECT l.id, ', @sql, ' FROM lines l JOIN types t ON l.type_id = t.id GROUP BY l.id'); -- 执行动态SQL PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
不同数据库的动态SQL差异
- SQL Server:用
EXEC sp_executesql @sql代替PREPARE/EXECUTE语句 - PostgreSQL:用
EXECUTE format(...)来完成拼接和执行操作
注意点
- 如果类型名称包含空格、特殊字符,要记得用反引号(MySQL)或方括号(SQL Server)包裹列名
- 确保
types.name的内容可信,避免SQL注入风险
内容的提问来源于stack exchange,提问作者python_help
相关产品推荐
相关产品推荐

