如何实现SQL查询:从多记录结果生成单条多列记录?MySQL场景求助
解决MySQL行转列:将多语言商品记录合并为单条多列记录
嘿,我来帮你搞定这个问题!从你的表结构来看,CommodityName应该是用来存储同一件商品(通过commodity_details_id关联)的多语言名称和描述,现在你想把同一商品的不同语言信息从多条记录合并成一条包含多列的记录,对吧?
下面分两种常见场景给你解决方案:
场景1:已知需要转换的固定语言ID
如果你的系统里语言是固定的(比如language_id=1对应英文,language_id=2对应中文),可以直接用CASE WHEN配合GROUP BY来实现行转列:
SELECT commodity_details_id, -- 提取language_id=1的商品名称和描述 MAX(CASE WHEN language_id = 1 THEN commodity_name END) AS name_en, MAX(CASE WHEN language_id = 1 THEN description END) AS desc_en, -- 提取language_id=2的商品名称和描述 MAX(CASE WHEN language_id = 2 THEN commodity_name END) AS name_zh, MAX(CASE WHEN language_id = 2 THEN description END) AS desc_zh -- 可以继续添加更多language_id对应的列 FROM CommodityName GROUP BY commodity_details_id;
为什么用MAX?
因为同一commodity_details_id分组下,每个language_id只会对应一条记录(假设数据没有重复),其他语言的CASE结果会是NULL,MAX函数会自动忽略NULL,保留有效的非空值。如果你的数据里存在同一commodity_details_id+language_id的重复记录,建议先给这两个字段加唯一索引,避免结果异常。
场景2:语言ID不固定(动态生成列)
如果你的系统会新增语言,不想每次修改SQL,可以用MySQL的动态SQL+存储过程来自动生成所有语言对应的列:
DELIMITER // CREATE PROCEDURE PivotCommodityNames() BEGIN -- 第一步:收集所有不同的language_id,拼接成对应的列语句 SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(CASE WHEN language_id = ', language_id, ' THEN commodity_name END) AS name_lang', language_id, ',', 'MAX(CASE WHEN language_id = ', language_id, ' THEN description END) AS desc_lang', language_id ) ) INTO @sql FROM CommodityName; -- 第二步:拼接完整的查询SQL SET @sql = CONCAT('SELECT commodity_details_id, ', @sql, ' FROM CommodityName GROUP BY commodity_details_id'); -- 第三步:执行动态生成的SQL PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END // DELIMITER ; -- 调用存储过程获取结果 CALL PivotCommodityNames();
这个存储过程的逻辑:
- 先查询表中所有唯一的
language_id,自动拼接出每个语言对应的name_langX和desc_langX列。 - 把这些列拼接成完整的SELECT语句。
- 预处理并执行这条动态SQL,返回合并后的结果。
额外提醒
- 你的表用的是
latin1字符集,如果存储非英文的语言(比如中文、日文),可能会出现乱码问题,建议考虑把字符集改成utf8mb4,支持更多字符。 - 如果不需要保留所有商品,只想查询特定商品,可以在
FROM后面加WHERE commodity_details_id = 你的商品ID。
内容的提问来源于stack exchange,提问作者AndreaNobili
相关产品推荐
相关产品推荐

