我希望有人可以帮助我。我是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)在做什么吗?
答案 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将=
符号左侧的完整值(而不是字符串包含操作类型)与右侧的每个参数进行比较。