SQL Server子查询返回多行错误排查与修正求助
这个错误的根源很明确——你嵌入CASE语句的子查询没有和主查询的当前行做关联,所以它会返回所有包含"dispatch level: "的行的结果,而CASE表达式每次只能接受单个值,这就触发了"subquery returned more than 1 value"错误。
接下来给你几个解决思路,从修复原代码到更简洁的替代方案:
方案1:修复原CASE子查询(添加关联条件)
你只需要给子查询加上和主表当前行的IncidentId关联的条件,确保子查询只返回当前行对应的结果:
select incidentid, case when CadRemarks like '%dispatch level: %' then ( select LEFT(tt.CadRemarks, charindex(' ', tt.CadRemarks) - 1) from IncidentMisc t cross apply ( values (substring(t.CadRemarks, charindex('dispatch level: ', t.CadRemarks) + 16, len(t.CadRemarks))) ) tt(CadRemarks) where t.IncidentId = main.IncidentId -- 关键:关联主查询的当前行 ) else '' end as CallType from IncidentMisc main -- 给主表起别名用于关联
方案2:用OUTER APPLY简化查询(推荐)
这种方式更简洁高效,不需要嵌套子查询,一次就能处理所有行(包括没有匹配关键词的行):
select main.IncidentId, ISNULL( CASE WHEN charindex(' ', tt.extracted) > 0 THEN LEFT(tt.extracted, charindex(' ', tt.extracted) - 1) ELSE tt.extracted END, '' ) as CallType from IncidentMisc main outer apply ( -- 只对包含关键词的行提取后续内容 select substring(main.CadRemarks, charindex('dispatch level: ', main.CadRemarks) + 16, len(main.CadRemarks)) as extracted where main.CadRemarks like '%dispatch level: %' ) tt order by main.IncidentId
这里的OUTER APPLY会保留主表的所有行:
- 如果行包含"dispatch level: ",就提取关键词后的内容,再截取到第一个空格前的部分;
- 如果关键词后没有空格(边界情况),就直接取全部后续内容;
- 如果没有关键词,
tt.extracted为NULL,用ISNULL转成空字符串,正好符合你的期望输出。
方案3:用计算列直接处理
如果你不需要额外的子查询/APPLY,也可以直接在SELECT里用嵌套函数处理,不过可读性稍差:
select IncidentId, CASE WHEN CadRemarks like '%dispatch level: %' THEN CASE WHEN charindex(' ', SUBSTRING(CadRemarks, charindex('dispatch level: ', CadRemarks) + 16, len(CadRemarks))) > 0 THEN LEFT(SUBSTRING(CadRemarks, charindex('dispatch level: ', CadRemarks) + 16, len(CadRemarks)), charindex(' ', SUBSTRING(CadRemarks, charindex('dispatch level: ', CadRemarks) + 16, len(CadRemarks))) - 1) ELSE SUBSTRING(CadRemarks, charindex('dispatch level: ', CadRemarks) + 16, len(CadRemarks)) END ELSE '' END as CallType from IncidentMisc order by IncidentId
内容的提问来源于stack exchange,提问作者LucasC922
相关产品推荐
相关产品推荐

