【问题标题】:SQL Logic Operator Precedence: And and OrSQL 逻辑运算符优先级:与和或
【发布时间】:2023-03-31 20:22:02
【问题描述】:

下面的两个语句是等价的吗?

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

我可以使用某种真值表来验证这一点吗?

【问题讨论】:

  • 尝试:T T F.(T 或 T)和 F.T 或(T 和 F)。代码的读者应该能够清楚地看到代码作者的意图。作者需要确保机器正在按照他的意图进行操作。括号对齐所有三个:阅读器、作者和机器。 :)

标签: sql logical-operators operator-precedence


【解决方案1】:

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

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

【讨论】:

  • 即使不需要括号,也要使用括号。很少有程序员(如果有的话)知道所有可用运算符的优先级。
  • @Trismegistos 希望不是这样......不应该是这样,但我猜你是对的。
  • 这个AND 然后OR 优先级是SQL 标准的一部分吗?
  • @Jaime,是的,而且,afaik,它也是所有编程语言标准的一部分。
  • @Bsienn,不确定你做了什么,但这与标准 SQL 和 MySQL 文档不一致...dev.mysql.com/doc/refman/5.0/en/operator-precedence.html你应该再试一次,这次要小心...试试declare @x tinyInt = 1 declare @y tinyInt = 0declare @z tinyInt = 0select case when @x=1 or @y=1 and @z=1 then'T' else 'F' endselect case when (@x=1 or @y=1) and @z=1 then'T' else 'F' end
【解决方案2】:

我加2分:

  • “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 拆分并更改了优先级。

【讨论】:

  • gbn ORACLE SQL 中是否存在关联性?如果是,那么我如何以及在哪里可以获得所有运算符的关联性?
  • 尽管说起来让我很痛苦,但在红宝石中 AND 并没有优先于 OR !更糟糕的是,&& 确实 优先于 ||!我不喜欢 ruby​​ 的原因之一——它一次又一次地违反了我最不惊讶的原则。 2.2.1 :007 > 真或真假 => 假 2.2.1 :008 > 真 ||真 && 假 => 真
【解决方案3】:
  1. 算术运算符
  2. 连接运算符
  3. 比较条件
  4. IS [NOT] NULL、LIKE、[NOT] IN
  5. [不] 之间
  6. 不等于
  7. 非逻辑条件
  8. AND 逻辑条件
  9. OR 逻辑条件

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

【讨论】:

    【解决方案4】:

    查询以显示 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
    

    【讨论】:

      猜你喜欢
      • 2019-08-03
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多