如何在CASE语句中设置局部变量并拼接查询结果?遇语法报错及结果异常
解决SQL中CASE语句赋值变量及多行值拼接问题
嘿,我来帮你搞定这个SQL的问题~你遇到的语法错误和拼接结果不符合预期的问题,其实是因为用错了变量赋值的方式,而且CASE语句本身没法实现多行值的拼接。咱们一步步来解决:
错误原因分析
- CASE语句里的赋值语法错误:CASE是一个表达式,它只能返回一个值,不能用来执行赋值操作(比如
@strSpeaker += ...这种写法是不允许的),这就是你看到“=”处语法错误的核心原因。 - 单个结果的问题:就算你强行在SELECT里给变量赋值,这种方式只会保留最后一条匹配记录的赋值结果,没法把多个行的
USR_ID拼接成一个完整的字符串。
正确的解决方案
根据你的SQL Server版本,有两种简洁的实现方式:
方式1:SQL Server 2017及以上版本(推荐)
用STRING_AGG函数直接实现多行字符串拼接,这是官方推荐的现代写法:
SELECT EM.EVT_REFCODE, EM.EVT_DESC, -- 拼接每个EVT_REFCODE对应的所有USR_ID,用逗号分隔,自动过滤NULL值 STRING_AGG(UM.USR_ID, ',') WITHIN GROUP (ORDER BY UM.USR_ID) AS SpeakerList FROM [CSEventDB2].[dbo].[EVENT_MASTER] EM LEFT JOIN [CSEventDB2].[dbo].[EVENT_PIC] EP ON EP.EVT_REFCODE = EM.EVT_REFCODE LEFT JOIN [CSEventDB2].[dbo].[USER_MASTER] UM ON UM.USR_REFCODE = EP.USR_REFCODE -- 按主表字段分组,确保每个事件对应一条拼接结果 GROUP BY EM.EVT_REFCODE, EM.EVT_DESC
解释:STRING_AGG会自动把分组内的所有USR_ID用逗号拼接起来,WITHIN GROUP可以指定拼接的顺序,完美匹配你的需求。
方式2:SQL Server 2016及更早版本
如果你的版本不支持STRING_AGG,可以用经典的STUFF + FOR XML PATH组合来实现拼接:
SELECT EM.EVT_REFCODE, EM.EVT_DESC, -- 用STUFF去掉开头的逗号,FOR XML PATH实现多行拼接 STUFF( ( SELECT ',' + UM.USR_ID FROM [CSEventDB2].[dbo].[EVENT_PIC] EP LEFT JOIN [CSEventDB2].[dbo].[USER_MASTER] UM ON UM.USR_REFCODE = EP.USR_REFCODE WHERE EP.EVT_REFCODE = EM.EVT_REFCODE FOR XML PATH(''), TYPE ).value('.', 'varchar(90)'), 1, 1, '' ) AS SpeakerList FROM [CSEventDB2].[dbo].[EVENT_MASTER] EM
解释:
- 子查询里用
FOR XML PATH('')把每个USR_ID拼接成带逗号的字符串(比如,ID1,ID2) STUFF函数把开头的逗号去掉,得到最终的ID1,ID2格式TYPE和.value('.', 'varchar(90)')是为了避免特殊字符被XML转义
额外说明
你原来的查询里还关联了EVENT_SPEAKER和PARTICIPANT_MASTER,但看起来这些表没有用到,如果是你需求里的遗漏,可以把它们加到对应的关联逻辑里哦~
内容的提问来源于stack exchange,提问作者Dya
相关产品推荐
相关产品推荐

