下面两种说法是否相同?

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

and

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

有什么真值表可以用来验证吗?


并且优先于或,因此,即使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

对于喜欢查阅参考资料(按字母顺序排列)的读者:

Microsoft Transact-SQL操作符优先级 Oracle MySQL 9操作符优先级 Oracle 10g条件优先级 PostgreSQL操作符优先级 SQLite理解的SQL


我补充两点:

“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拆开了,并改变了优先级。


算术运算符 连接运算符 比较条件 [not]是null,就像[not] in吗 (不)之间 不等于 非逻辑条件 与逻辑条件 或逻辑条件

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


查询一个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

下面是使用布尔值的“3变量真值表”的一个变体

WITH truth_values AS
  (SELECT FALSE AS A,        
          FALSE AS B,
          FALSE AS C
   UNION ALL SELECT FALSE,
                    FALSE,
                    TRUE
   UNION ALL SELECT FALSE,
                    TRUE,
                    FALSE
   UNION ALL SELECT FALSE,
                    TRUE,
                    TRUE
   UNION ALL SELECT TRUE,
                    FALSE,
                    FALSE
   UNION ALL SELECT TRUE,
                    FALSE,
                    TRUE
   UNION ALL SELECT TRUE,
                    TRUE,
                    FALSE
   UNION ALL SELECT TRUE,
                    TRUE,
                    TRUE),
     logics AS
  (SELECT truth_values.*,
          a
   OR b
   AND c AS no_parens, (a
                        OR b)
   AND c AS or_parens
   FROM truth_values)
SELECT *,
       no_parens != or_parens AS parens_made_a_difference
FROM logics
ORDER BY a,
         b,
         c

这些结果:

# A B C no_parens or_parens parens_made_a_difference
1 false false false false false false
2 false false true false false false
3 false true false false false false
4 false true true true true false
5 true false false true false true
6 true false true true true false
7 true true false true false true
8 true true true true true false

如果'parens_made_a_difference'为真,则括号起作用。