如何修改含内连接与分组的SQL查询,合并重复分类的描述字段?
解决同一分类下多条描述合并的SQL查询问题
这是个非常常见的分组聚合需求,核心就是用字符串聚合函数把同一category下的多条description记录合并成一个用-分隔的字符串。不同数据库的实现语法略有差异,我给你分情况说明,同时还会修正你原查询里的小问题(原查询的GROUP BY id_p应该改成按category分组,否则达不到按分类合并的效果):
1. MySQL/MariaDB 版本
使用GROUP_CONCAT函数,指定分隔符为' - '即可:
SELECT category, GROUP_CONCAT(description SEPARATOR ' - ') AS description FROM `players` INNER JOIN orders ON orders.id_player = players.player GROUP BY category;
GROUP_CONCAT会自动把同一分组(这里是同一个category)内的所有description值拼接起来,SEPARATOR参数用来指定分隔符,默认是逗号,我们改成你需要的' - '就行。
2. PostgreSQL 版本
用STRING_AGG函数实现,语法更直观:
SELECT category, STRING_AGG(description, ' - ') AS description FROM players INNER JOIN orders ON orders.id_player = players.player GROUP BY category;
3. SQL Server 版本
- 2017及以上版本:同样支持
STRING_AGG,写法和PostgreSQL类似:
SELECT category, STRING_AGG(description, ' - ') AS description FROM players INNER JOIN orders ON orders.id_player = players.player GROUP BY category;
- 旧版本(2016及以前):需要用
FOR XML PATH的方式模拟字符串聚合:
SELECT DISTINCT category, STUFF(( SELECT ' - ' + description FROM orders o INNER JOIN players p ON o.id_player = p.player WHERE p.category = players.category FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 3, '') AS description FROM players INNER JOIN orders ON orders.id_player = players.player;
这里STUFF函数是用来去掉拼接结果开头多余的' - '(从第1位开始,删除3个字符)。
4. Oracle 版本
使用LISTAGG函数,还可以指定拼接顺序:
SELECT category, LISTAGG(description, ' - ') WITHIN GROUP (ORDER BY description) AS description FROM players INNER JOIN orders ON orders.id_player = players.player GROUP BY category;
如果不需要固定拼接顺序,去掉ORDER BY description即可。
内容的提问来源于stack exchange,提问作者cloude
相关产品推荐
相关产品推荐

