SQL Server中如何将一个字段的多个记录值合成一起显示

本文介绍了一种使用SQL函数实现将同一单位名称下的不同收费类别进行拼接的方法。通过创建一个存储过程来实现字符串的拼接,并展示了如何调用该函数以获取预期的输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有下表:   

   单位名称  

收费类别

1

a

1

b

1

d

2

a

3

b

3

c

 

要求查询结果显示如下   

单位名称

收费类别

1

a,b,d  

2

a

3

b,c 

 

函数实现
create   function   getstr(@
单位名称   int)  
  returns   varchar(2000)  
  as    
  begin  
  declare   @str   varchar(2000)  
  set   @str=''  
  select   @str=@str+','+rtrim(
收费类别)   from     where   单位名称=@单位名称  
  select   @str=right(@str,len(@str)-1)   where   @str<>''  
  return   @str  
  end  
  go  
   
  --
调用:  
  select  
单位名称,dbo.getstr(单位名称)   收费类别     from     group   by   单位名称 
SQL Server 中,将多行数据合并为一行是常见的需求,尤其在需要展示聚合信息时。SQL Server 本身没有像 MySQL 的 `GROUP_CONCAT` 或 Oracle 的 `LISTAGG` 这样的内置函数来直接实现这一功能,但可以通过组合使用 `STUFF` 和 `FOR XML PATH` 来达到目的。 ### 使用 `STUFF` 和 `FOR XML PATH` 这种方法通过子查询生成一个 XML 字符串,然后使用 `STUFF` 函数去除开头或结尾的多余字符(如逗号),从而形成一个以逗号分隔的字符串。 #### 示例 假设有一个表 `#TEST`,其结构如下: ```sql CREATE TABLE #TEST ( ID INT, course NVARCHAR(100) ); ``` 插入一些测试数据: ```sql INSERT INTO #TEST (ID, course) VALUES (1, 'Math'), (1, 'Science'), (1, 'History'), (2, 'English'), (2, 'Literature'); ``` 要将每个 `ID` 对应的 `course` 合并成一行,并用逗号分隔,可以使用以下查询: ```sql SELECT ID, STUFF(( SELECT ',' + course FROM #TEST t2 WHERE t2.ID = t1.ID FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS courses FROM #TEST t1 GROUP BY ID; ``` #### 解释 - **`FOR XML PATH('')`**:将子查询结果转换为 XML 格式,并且不添加任何额外的标签。 - **`TYPE`**:确保返回的结果是 XML 类型,以便后续使用 `.value()` 方法提取字符串。 - **`.value('.', 'NVARCHAR(MAX)')`**:从 XML 数据中提取纯字符串。 - **`STUFF(..., 1, 1, '')`**:移除字符串开头的多余逗号。 ### 去重处理 如果存在重复并且希望去重,可以在子查询中加入 `DISTINCT` 关键字: ```sql SELECT ID, STUFF(( SELECT DISTINCT ',' + course FROM #TEST t2 WHERE t2.ID = t1.ID FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS courses FROM #TEST t1 GROUP BY ID; ``` ### 复杂场景示例 当需要对多个字段进行合并和聚合操作时,可以结合 `CTE`(Common Table Expression)和 `GROUP BY` 实现更复杂的逻辑。例如: ```sql WITH CTE AS ( SELECT a.F_ID id, a.F_Code code, b.F_Name name, b.F_SQZSL num, 0 price, F_SQBMCode department FROM t_wms_out a LEFT JOIN t_wms_out_detail b ON a.F_ID = b.F_OutId WHERE a.F_SQLX = '100' AND a.F_ZZId = '3001' ) SELECT id, code, STUFF(( SELECT ',' + name FROM CTE c2 WHERE c2.id = c1.id FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS name, SUM(num) AS num, SUM(price) AS price, department FROM CTE c1 GROUP BY id, code, department; ``` 这个例子展示了如何在一个更复杂的查询中使用 `STUFF` 和 `FOR XML PATH` 来合并多个字段,并结合 `SUM` 等聚合函数。 ### 性能注意事项 虽然 `STUFF` 和 `FOR XML PATH` 是一种常见且有效的解决方案,但在处理大规模数据集时可能会导致性能下降。此时可以考虑使用自定义聚合函数(通过 CLR 集成)或临时表等其他优化手段。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值