将同Name值的FKId合并到同一行的SQL查询问题
问题解决:按Name合并FKId并聚合统计
问题背景
现有查询返回以下结果:
| Id | FKId | Count1 | Count2 | CountAll | Name | OriginalName |
|---|---|---|---|---|---|---|
| 1 | 100 | 1 | 0 | 1 | Food | 某个值 |
| 1 | 101 | 0 | 1 | 1 | Drink | 某个值 |
| 1 | 102 | 1 | 0 | 1 | Drink | 某个值 |
需要将相同Name的所有FKId合并为一行,同时聚合Count1、Count2和CountAll,期望结果如下:
| Id | FKId | Count1 | Count2 | CountAll | Name | OriginalName |
|---|---|---|---|---|---|---|
| 1 | 100 | 1 | 0 | 1 | Food | 某个值 |
| 1 | 101, 102 | 1 | 1 | 2 | Drink | 某个值 |
当前生成3行结果的查询语句:
SELECT t1.Id, t2.FkId, COUNT(some case when here) [Count1], COUNT(some case when here) [Count2], COUNT(t2.FkId) [CountAll], t3.Name, t3.OriginalName FROM table1 t1 JOIN table2 t2 ON t1.Id = t2.Id JOIN table3 t3 ON t2.FKId = t3.FkId GROUP BY t1.Id, t2.FkId, t3.Name, t3.OriginalName
尝试添加以下代码时触发语法错误:
DECLARE @Ids VARCHAR(8000) (SELECT @Ids= COALESCE(@Ids+ ', ', '') + t2.FkId),
错误提示:
在 '=' 附近有语法错误。
解决方案
核心问题分析
- 原查询的
GROUP BY包含t2.FkId,导致每个FKId单独分组生成一行,不符合需求,需要移除t2.FkId,改为按Name等字段分组。 - 你尝试的变量拼接写法存在语法错误,且这种方式无法直接实现分组聚合场景下的字符串拼接,推荐使用更适配的字符串聚合方案。
方案1:使用STRING_AGG(SQL Server 2017+)
这是最简洁的实现方式,直接用STRING_AGG函数合并同组的FKId,同时调整聚合逻辑:
SELECT t1.Id, STRING_AGG(t2.FkId, ', ') AS FKId, SUM(CASE WHEN [你的条件] THEN 1 ELSE 0 END) AS Count1, -- 用SUM替代COUNT更精准统计符合条件的记录数 SUM(CASE WHEN [你的条件] THEN 1 ELSE 0 END) AS Count2, COUNT(t2.FkId) AS CountAll, t3.Name, t3.OriginalName FROM table1 t1 JOIN table2 t2 ON t1.Id = t2.Id JOIN table3 t3 ON t2.FKId = t3.FkId GROUP BY t1.Id, t3.Name, t3.OriginalName -- 按Name等字段分组,不再按FKId分组
方案2:使用FOR XML PATH(兼容低版本SQL Server)
如果你的SQL Server版本低于2017,无法使用STRING_AGG,可以用XML拼接的方式实现:
SELECT t1.Id, STUFF((SELECT ', ' + CAST(t2_sub.FkId AS VARCHAR(10)) FROM table2 t2_sub JOIN table3 t3_sub ON t2_sub.FKId = t3_sub.FkId WHERE t1.Id = t2_sub.Id AND t3.Name = t3_sub.Name FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, '') AS FKId, SUM(CASE WHEN [你的条件] THEN 1 ELSE 0 END) AS Count1, SUM(CASE WHEN [你的条件] THEN 1 ELSE 0 END) AS Count2, COUNT(t2.FkId) AS CountAll, t3.Name, t3.OriginalName FROM table1 t1 JOIN table2 t2 ON t1.Id = t2.Id JOIN table3 t3 ON t2.FKId = t3.FkId GROUP BY t1.Id, t3.Name, t3.OriginalName
关于你尝试的代码错误说明
你写的变量拼接语句语法不正确,正确的变量拼接写法如下(但此方式仅适用于全局拼接,无法实现分组拼接):
DECLARE @Ids VARCHAR(8000) = '' SELECT @Ids = COALESCE(@Ids + ', ', '') + CAST(t2.FkId AS VARCHAR(10)) FROM table2 t2
内容的提问来源于stack exchange,提问作者User1899289003
相关产品推荐
相关产品推荐

