You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何改写SQL Server 2014中的CASE表达式以消除指定错误?

解决SQL Server中IN子查询多列的错误问题

首先,咱们来拆解你遇到的错误:Only one expression can be specified in the select list when the subquery is not introduced with EXISTS,这个错误的核心原因是你在IN后面的子查询返回了6列数据,但IN子查询要求只能返回单列——它要的是一组值,不是多列的结果集。另外还有个隐藏问题:你子查询里的WHERE [ID] = [ID] -2是引用子查询内部的ID,等价于0=-2,永远不会匹配到任何行,所以就算不报错,结果也全是0,不符合你的需求。

接下来给你两种修正方案,都能实现你的预期效果:

方案1:使用自连接(最直观)

通过LEFT JOIN直接关联当前行和ID减2的行,然后在CASE语句里直接判断当前列的值是否存在于关联行的6个列中:

USE MyDatabase
SELECT 
    t.*,
    CASE WHEN t.N1 IN (t_prev.N1, t_prev.N2, t_prev.N3, t_prev.N4, t_prev.N5, t_prev.N6) THEN 1 ELSE 0 END AS [N1_ID-2],
    CASE WHEN t.N2 IN (t_prev.N1, t_prev.N2, t_prev.N3, t_prev.N4, t_prev.N5, t_prev.N6) THEN 1 ELSE 0 END AS [N2_ID-2],
    CASE WHEN t.N3 IN (t_prev.N1, t_prev.N2, t_prev.N3, t_prev.N4, t_prev.N5, t_prev.N6) THEN 1 ELSE 0 END AS [N3_ID-2],
    CASE WHEN t.N4 IN (t_prev.N1, t_prev.N2, t_prev.N3, t_prev.N4, t_prev.N5, t_prev.N6) THEN 1 ELSE 0 END AS [N4_ID-2],
    CASE WHEN t.N5 IN (t_prev.N1, t_prev.N2, t_prev.N3, t_prev.N4, t_prev.N5, t_prev.N6) THEN 1 ELSE 0 END AS [N5_ID-2],
    CASE WHEN t.N6 IN (t_prev.N1, t_prev.N2, t_prev.N3, t_prev.N4, t_prev.N5, t_prev.N6) THEN 1 ELSE 0 END AS [N6_ID-2]
FROM [T1] t
LEFT JOIN [T1] t_prev ON t_prev.ID = t.ID - 2

为什么这样能行?

  • LEFT JOIN会把当前行(别名t)和ID恰好小2的行(别名t_prev)关联起来,对于ID=1、2的行,因为没有ID=-1、0的行,t_prev的所有列都是NULL,IN判断会返回false,所以结果是0,正好符合你的预期。
  • 这里的IN后面是直接列出t_prev的6个列值,属于“多值匹配”,是IN的合法用法,避免了子查询多列的问题。

方案2:使用EXISTS子查询(更灵活)

如果后续需要扩展列数,这种方式更容易维护,通过VALUES把t_prev的6列转成单行多值的结果集,再用EXISTS判断是否匹配:

USE MyDatabase
SELECT 
    t.*,
    CASE WHEN EXISTS (
        SELECT 1 
        FROM (VALUES (t_prev.N1), (t_prev.N2), (t_prev.N3), (t_prev.N4), (t_prev.N5), (t_prev.N6)) AS vals(value)
        WHERE vals.value = t.N1
    ) THEN 1 ELSE 0 END AS [N1_ID-2],
    CASE WHEN EXISTS (
        SELECT 1 
        FROM (VALUES (t_prev.N1), (t_prev.N2), (t_prev.N3), (t_prev.N4), (t_prev.N5), (t_prev.N6)) AS vals(value)
        WHERE vals.value = t.N2
    ) THEN 1 ELSE 0 END AS [N2_ID-2],
    CASE WHEN EXISTS (
        SELECT 1 
        FROM (VALUES (t_prev.N1), (t_prev.N2), (t_prev.N3), (t_prev.N4), (t_prev.N5), (t_prev.N6)) AS vals(value)
        WHERE vals.value = t.N3
    ) THEN 1 ELSE 0 END AS [N3_ID-2],
    CASE WHEN EXISTS (
        SELECT 1 
        FROM (VALUES (t_prev.N1), (t_prev.N2), (t_prev.N3), (t_prev.N4), (t_prev.N5), (t_prev.N6)) AS vals(value)
        WHERE vals.value = t.N4
    ) THEN 1 ELSE 0 END AS [N4_ID-2],
    CASE WHEN EXISTS (
        SELECT 1 
        FROM (VALUES (t_prev.N1), (t_prev.N2), (t_prev.N3), (t_prev.N4), (t_prev.N5), (t_prev.N6)) AS vals(value)
        WHERE vals.value = t.N5
    ) THEN 1 ELSE 0 END AS [N5_ID-2],
    CASE WHEN EXISTS (
        SELECT 1 
        FROM (VALUES (t_prev.N1), (t_prev.N2), (t_prev.N3), (t_prev.N4), (t_prev.N5), (t_prev.N6)) AS vals(value)
        WHERE vals.value = t.N6
    ) THEN 1 ELSE 0 END AS [N6_ID-2]
FROM [T1] t
LEFT JOIN [T1] t_prev ON t_prev.ID = t.ID - 2

这种方式的优势:

如果以后你的表增加了N7、N8这类列,只需要修改VALUES里的列表即可,不需要改动IN里的多个列名,维护起来更方便。

内容的提问来源于stack exchange,提问作者user3115933

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 14:52:36