我需要知道IN(@sub)在本声明中的含义

时间:2014-01-22 22:01:09

标签: sql-server tsql

我希望有人可以帮助我。我是SQL新手,遇到了以下代码:

FROM
    Job_List j1 
INNER JOIN 
    Item_List i1 ON j1.Control_No = i1.Control_No
WHERE
    CONVERT(DATE,j1.Settlement_Date_Actual) >= CONVERT(DATE,@sday)
    AND CONVERT(DATE,j1.Settlement_Date_Actual) <= CONVERT(DATE,@eday)
    AND j1.Supplier_No IN(@supplier)
    AND CASE
          WHEN j1.Sub_Client IS NULL THEN '(BLANK)'
          WHEN j1.Sub_Client = '' THEN '(BLANK)' 
          ELSE J1.Sub_Client 
    END IN(@sub)

***有人能解释一下IN(@sub)在做什么吗?

2 个答案:

答案 0 :(得分:1)

表达式是:

CASE WHEN j1.Sub_Client IS NULL THEN '(BLANK)'
     WHEN j1.Sub_Client = '' THEN '(BLANK)' 
     ELSE J1.Sub_Client 
END IN (@sub)

您不是在问case,所以让我们举个例子J1.Sub_Client IN (@sub)

实际上意味着:

    J1.Sub_Client = @sub

编写它的人可能认为他们可以在@sub中添加逗号分隔列表。在这种情况下,该人会错误地认为以下内容是等效的(假设@sub是'a,b,c'):

J1.Sub_Client in (@sub)
J1.Sub_Client in ('a', 'b', 'c')
J1.Sub_Client = 'a' or J1.Sub_Client = 'b' or J1.Sub_Client = 'c'

最后两个是等价的。首先测试J1.Sub_Client和字符串'a,b,c'之间的相等性 - 一个值,而不是三个。

答案 1 :(得分:1)

@sub听起来像是table variable,而IN(@sub)正在检查它前面的case语句的结果。

详细说明,

最后一行是案例陈述的一部分。

WHERE
    CONVERT(DATE,j1.Settlement_Date_Actual) >= CONVERT(DATE,@sday)
    AND CONVERT(DATE,j1.Settlement_Date_Actual) <= CONVERT(DATE,@eday)
    AND j1.Supplier_No IN(@supplier)
    AND CASE -- Begin case statement
          WHEN j1.Sub_Client IS NULL THEN '(BLANK)'
          WHEN j1.Sub_Client = '' THEN '(BLANK)' 
          ELSE J1.Sub_Client 
    END IN(@sub) -- Case statement ends, and the result is the value checked against the @sub table variable

简化,

WHERE
    CONVERT(DATE,j1.Settlement_Date_Actual) >= CONVERT(DATE,@sday)
    AND CONVERT(DATE,j1.Settlement_Date_Actual) <= CONVERT(DATE,@eday)
    AND j1.Supplier_No IN(@supplier)
    AND 'SomeString' IN(@sub)

在这种情况下,“SomeString”由其前面的CASE语句决定,并使用J1.Sub_Client或值'(BLANK)'

<强>更新

由于注释,表变量的IN(@sub)语法错误。这必须是标量变量。但是,正如我上面所解释的那样,同样的概念也适用。 IN在这里的差异实际上是指一个值,而不是很多可能的值。

IN(@sub)工作的原因是因为IN使用一个参数,例如

IN('StackOverflow')

当IN仅与一个值一起使用时,它相当于写

= 'StackOverflow'

因为IN将=符号左侧的完整值(而不是字符串包含操作类型)与右侧的每个参数进行比较。