SQL逻辑运算符优先级:和和或

这两个陈述是否相同?

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 

有什么我可以用来validation这个真理表吗?

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 

我会加2分:

  • “IN”与他们周围的括号是有效的连续OR
  • 并且在我知道的每种语言中优先于OR

所以,这两个expression式根本不相等。

 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分开,改变优先级。

  1. 算术运算符
  2. 连接运算符
  3. 比较条件
  4. IS [NOT] NULL,LIKE,[NOT] IN
  5. [NOT] BETWEEN
  6. 不等于
  7. 不是逻辑条件
  8. AND逻辑条件
  9. OR逻辑条件

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

查询显示一个3variables布尔expression式真值表:

 ;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)

 ABC 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)

 ABC 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 

它们是相同的。 您没有指定数据库types,所以这里是SQL Server 2005中的示例。

 with temp as ( select 'a' as type, 1 as some_col union select 'b' as type, 2 as some_col union select 'c' as type, 3 as some_col union select 'd' as type, 4 as some_col union select 'e' as type, 5 as some_col union select 'f' as type, 6 as some_col ) select * from temp where some_col in (1,2) or some_col in (3) select * from temp where some_col in (1,2,3) 
Interesting Posts