211

下面的两种说法是等价的吗?

SELECT [...]
FROM [...]
WHERE some_col in (1,2,3,4,5) AND some_other_expr

SELECT [...]
FROM [...]
WHERE some_col in (1,2,3) or some_col in (4,5) AND some_other_expr

是否有某种真值表可以用来验证这一点?

4

4 回答 4

346

And优先于Or, 所以, 即使a <=> a1 Or a2

Where a And b 

不一样

Where a1 Or a2 And b,

因为那将被执行为

Where a1 Or (a2 And b)

为了使它们相同,您想要的是以下内容(使用括号覆盖优先规则):

 Where (a1 Or a2) And b

这里有一个例子来说明:

Declare @x tinyInt = 1
Declare @y tinyInt = 0
Declare @z tinyInt = 0

Select Case When @x=1 OR @y=1 And @z=1 Then 'T' Else 'F' End -- outputs T
Select Case When (@x=1 OR @y=1) And @z=1 Then 'T' Else 'F' End -- outputs F

对于那些喜欢查阅参考资料的人(按字母顺序):

于 2009-08-06T20:19:50.497 回答
40

我补充两点:

  • “IN”实际上是带有括号的串行 OR
  • 在我知道的每一种语言中,AND 都优先于 OR

因此,这两个表达式根本不相等。

WHERE some_col in (1,2,3,4,5) AND some_other_expr
--to the optimiser is this
WHERE
     (
     some_col = 1 OR
     some_col = 2 OR 
     some_col = 3 OR 
     some_col = 4 OR 
     some_col = 5
     )
     AND
     some_other_expr

因此,当您拆分 IN 子句时,您将串行 OR 拆分,并更改了优先级。

于 2009-08-07T05:20:55.150 回答
24
  1. 算术运算符
  2. 连接运算符
  3. 比较条件
  4. IS [NOT] NULL, LIKE, [NOT] IN
  5. [不] 之间
  6. 不等于
  7. 非逻辑条件
  8. AND 逻辑条件
  9. OR 逻辑条件

您可以使用括号来覆盖优先规则。

于 2014-03-27T22:49:31.933 回答
10

查询以显示 3 变量布尔表达式真值表:

;WITH cteData AS
(SELECT 0 AS A, 0 AS B, 0 AS C
UNION ALL SELECT 0,0,1
UNION ALL SELECT 0,1,0
UNION ALL SELECT 0,1,1
UNION ALL SELECT 1,0,0
UNION ALL SELECT 1,0,1
UNION ALL SELECT 1,1,0
UNION ALL SELECT 1,1,1
)
SELECT cteData.*,
    CASE WHEN

(A=1) OR (B=1) AND (C=1)

    THEN 'True' ELSE 'False' END AS Result
FROM cteData

结果(A=1) OR (B=1) AND (C=1)

A   B   C   Result
0   0   0   False
0   0   1   False
0   1   0   False
0   1   1   True
1   0   0   True
1   0   1   True
1   1   0   True
1   1   1   True

结果(A=1) OR ( (B=1) AND (C=1) )相同。

结果( (A=1) OR (B=1) ) AND (C=1)

A   B   C   Result
0   0   0   False
0   0   1   False
0   1   0   False
0   1   1   True
1   0   0   False
1   0   1   True
1   1   0   False
1   1   1   True
于 2015-06-18T14:29:33.387 回答