如何将同名称不同ID的行值合并到单个单元格?SQL实现需求
合并相同名称行的value字段方案
嘿,这个需求挺常见的,不同数据库系统都有对应的聚合函数来实现这种相同分组下的字符串合并效果,我给你整理几种常用数据库的解决方案:
MySQL/MariaDB
用GROUP_CONCAT函数就能搞定,它可以把分组内的字符串按指定分隔符拼接起来:
SELECT MIN(id) AS id, -- 这里选最小的id对应你示例里的1,也可以用MAX选最大的 name, GROUP_CONCAT(value SEPARATOR ' + ') AS value FROM demo GROUP BY name;
默认GROUP_CONCAT用逗号分隔,所以我们指定SEPARATOR ' + '来匹配你要的格式,通过GROUP BY name把同名称的行归为一组。
PostgreSQL
PostgreSQL用STRING_AGG函数,用法更直观:
SELECT MIN(id) AS id, name, STRING_AGG(value, ' + ') AS value FROM demo GROUP BY name;
如果需要按id顺序拼接(保证Text1、Text2、Text3的顺序),可以加上排序:
SELECT MIN(id) AS id, name, STRING_AGG(value, ' + ') ORDER BY id AS value FROM demo GROUP BY name;
SQL Server
2017及以上版本
同样支持STRING_AGG函数,写法和PostgreSQL类似:
SELECT MIN(id) AS id, name, STRING_AGG(value, ' + ') AS value FROM demo GROUP BY name;
2017之前的版本
需要用STUFF结合FOR XML PATH的组合来实现:
SELECT MIN(id) AS id, name, STUFF( (SELECT ' + ' + value FROM demo d2 WHERE d2.name = d1.name FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 3, '' -- 去掉开头多余的" + " ) AS value FROM demo d1 GROUP BY name;
子查询通过FOR XML PATH('')把同名称的value拼接成带" + "的字符串,再用STUFF删掉开头的三个字符(也就是第一个" + ")。
Oracle
Oracle用LISTAGG函数,还能指定拼接顺序:
SELECT MIN(id) AS id, name, LISTAGG(value, ' + ') WITHIN GROUP (ORDER BY id) AS value FROM demo GROUP BY name;
WITHIN GROUP (ORDER BY id)可以保证value按id的顺序拼接,和你示例里的Text1+Text2+Text3顺序一致。
内容的提问来源于stack exchange,提问作者user9326044
相关产品推荐
相关产品推荐

