nc.*_*nc. 164 sql operator-precedence logical-operators
以下两个陈述是否相同?
SELECT [...]
FROM [...]
WHERE some_col in (1,2,3,4,5) AND some_other_expr
Run Code Online (Sandbox Code Playgroud)
和
SELECT [...]
FROM [...]
WHERE some_col in (1,2,3) or some_col in (4,5) AND some_other_expr
Run Code Online (Sandbox Code Playgroud)
我可以使用某种真值表来验证这一点吗?
Cha*_*ana 268
And优先于Or,即使如此a <=> a1 Or a2
Where a And b
Run Code Online (Sandbox Code Playgroud)
是不一样的
Where a1 Or a2 And b,
Run Code Online (Sandbox Code Playgroud)
因为那将被执行为
Where a1 Or (a2 And b)
Run Code Online (Sandbox Code Playgroud)
你想要什么,使它们变得一样,是
Where (a1 Or a2) And b
Run Code Online (Sandbox Code Playgroud)
这是一个例子来说明:
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
Run Code Online (Sandbox Code Playgroud)
对于那些喜欢咨询参考文献的人(按字母顺序排列):
gbn*_*gbn 32
我会加2分:
所以,2个表达式根本不相等.
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
Run Code Online (Sandbox Code Playgroud)
因此,当您打破IN子句时,将串行OR分开,并更改优先级.
小智 22
您可以使用括号覆盖优先级规则.
查询以显示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
Run Code Online (Sandbox Code Playgroud)
结果(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
Run Code Online (Sandbox Code Playgroud)
结果(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
Run Code Online (Sandbox Code Playgroud)