SQL Server 2016中CASE WHEN按条件返回UNION ALL多行报错求解
错误原因
CASE 属于标量表达式,仅能返回单个值,你在THEN后传入返回多行结果的子查询,不符合语法规则,所以触发报错。
解决方案
SQL Server 2016环境下可以通过匹配数字序列的方式实现按条件返回指定行数的结果,不需要用UNION ALL拼接多段子查询。
写法1:依赖系统表快速实现(适合行需求不超过2047的场景)
master..spt_values 系统表的type='P'序列会返回0-2047的连续整数,直接用该序列匹配你需要的行数即可:
-- 先统计T0表的Docnum计数 DECLARE @doc_cnt INT = (SELECT COUNT(Docnum) FROM T0) -- 按条件返回对应行数的结果 SELECT '999' AS result_col FROM master..spt_values v WHERE v.type = 'P' AND v.number < CASE WHEN @doc_cnt = 1 THEN 5 WHEN @doc_cnt = 2 THEN 4 WHEN @doc_cnt = 3 THEN 3 ELSE 0 -- 不匹配条件时返回空结果 END
如果你的需求是匹配T0每行的Docnum值而非全表计数,改用CROSS APPLY写法:
SELECT res.val AS result_col FROM T0 CROSS APPLY ( SELECT TOP ( CASE WHEN T0.Docnum = 1 THEN 3 -- 你示例中要求的3行 WHEN T0.Docnum = 2 THEN 4 WHEN T0.Docnum = 3 THEN 3 ELSE 0 END ) '999' AS val FROM master..spt_values v WHERE v.type = 'P' ) res
写法2:自定义数字序列(无系统表依赖)
如果不想依赖系统表,自己构造CTE生成你需要的最大长度的数字序列即可:
-- 按需定义最大行数,这里写了5行,不够可以继续加 WITH num_seq(n) AS ( SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 ) SELECT '999' AS result_col FROM num_seq WHERE n <= CASE WHEN (SELECT COUNT(Docnum) FROM T0) = 1 THEN 5 WHEN (SELECT COUNT(Docnum) FROM T0) = 2 THEN 4 WHEN (SELECT COUNT(Docnum) FROM T0) = 3 THEN 3 ELSE 0 END
内容的提问来源于stack exchange,提问作者swetts
相关产品推荐
相关产品推荐

