如何在CASE语句中使用IN?附SQL代码示例及场景说明
如何在CASE语句中使用IN操作符?
嘿,我来帮你梳理这个问题~首先得明确:SQL里的CASE表达式不能直接返回布尔值(和咱们平时写的Python、Java这类编程语言不一样),你原来的写法会触发语法错误,因为CASE的每个分支必须返回一个具体的数值/字符串等值,而不能直接返回T_MW.Currency IN (...)这种布尔判断结果。
最优解决方案:不用CASE,直接用逻辑运算符组合
其实你的需求是「当参数不为空时才启用IN过滤,为空时就跳过该条件」,完全可以用OR逻辑来实现,写法更简洁高效:
SELECT T_MW.* INTO #temp FROM T_MWP T_MW WHERE T_MW.CompanyID = 2 -- 当@Currency为空时,这部分条件直接为真,相当于不过滤;不为空时检查是否在临时表中 AND (@Currency IS NULL OR T_MW.Currency IN (SELECT * FROM #Currency)) -- 资产过滤逻辑同理 AND (@Asset IS NULL OR T_MW.Asset IN (SELECT * FROM #Asset))
这种写法不仅符合SQL语法规范,执行效率也比嵌套CASE更高,可读性也更强。
如果一定要用CASE的写法(不推荐,但满足需求)
要是你坚持要用CASE来实现,得把IN的判断转换成返回1/0的形式,再和1做比较,比如:
SELECT T_MW.* INTO #temp FROM T_MWP T_MW WHERE T_MW.CompanyID = 2 AND ( CASE WHEN @Currency IS NOT NULL THEN -- 内层CASE判断IN结果,符合返回1,不符合返回0 CASE WHEN T_MW.Currency IN (SELECT * FROM #Currency) THEN 1 ELSE 0 END ELSE 1 -- 参数为空时直接返回1,相当于满足条件 END ) = 1 AND ( CASE WHEN @Asset IS NOT NULL THEN CASE WHEN T_MW.Asset IN (SELECT * FROM #Asset) THEN 1 ELSE 0 END ELSE 1 END ) = 1
额外注意事项
你用SELECT * INTO #Asset FROM dbo.Split(@Asset, ',')创建临时表时,要确保Split函数返回的列类型和T_MW.Asset完全匹配,同理#Currency的列类型要和T_MW.Currency匹配,避免因类型不兼容导致的过滤错误。
内容的提问来源于stack exchange,提问作者NoOneJr
相关产品推荐
相关产品推荐

