MySQL语句中使用OR的确如何与/不用括号有什么不同?

时间:2011-02-02 08:24:37

标签: sql mysql

我有这个问题:

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
    AND `status` = 'active' OR `status` = 'past due'

哪个不能返回正确的结果。但是,在OR条件周围添加括号使其工作如下:

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
    AND (`status` = 'active' OR `status` = 'past due')

我的问题是为什么它有所不同?据我所知,在没有括号的情况下,OR语句会有所不同;但我不明白它是如何不同的。

我没有找到任何对此有帮助的文档。如果那里有任何链接,我真的很感激。

8 个答案:

答案 0 :(得分:24)

这是因为OR比AND低operator precedence。每当数据库看到类似

的表达式时
A AND B OR C

首先评估AND,即它等同于

(A AND B) OR C

所以如果你明确想要

A AND (B OR C)

相反,你必须放入括号。

这不是特定于SQL的。这些运算符的优先顺序在我所知的所有编程语言中都是相同的(即至少是C,C ++,C#,Java和Unix shell脚本)。

答案 1 :(得分:5)

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
AND `status` = 'active' OR `status` = 'past due'

在此示例中,您将获得所有记录

a)date_next_payment在2011年2月2日之前且状态为活动

b)状态为past_due

所以past_due记录不受日期限制。

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND (`status` = 'active' OR `status` = 'past due')

在此示例中,您将获得所有记录

a)date_next_payment在2011年2月2日之前

b)状态为active或past_due

括号的工作方式与数学或逻辑中的一样 - 括号内的语句首先得到评估......所以想象看到每个步骤都是这样的:

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND (`status` = 'active' OR `status` = 'past due')

因此遇到状态为活动的记录......

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND (TRUE OR FALSE)

然后使用OR条件评估...(TRUE或FALSE)== TRUE

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND TRUE

日期是2011-01-01

SELECT * FROM (`users`) WHERE TRUE
AND TRUE

最后,TRUE AND TRUE == TRUE

SELECT * FROM (`users`) WHERE TRUE

所以记录被返回......

想象您的查询是按照这样的步骤对数据库中的每一行执行的,有时会有助于理解放置括号的位置。

答案 2 :(得分:2)

in

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
    AND `status` = 'active' OR `status` = 'past due'

它将首先考虑date_next_payment <= '2011-02-02' AND status = 'active',然后对此进行布尔答案或与status = 'past due'

进行

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
    AND (`status` = 'active' OR `status` = 'past due')

首先完成OR然后将完成...那就是这将给出不同的答案

答案 3 :(得分:2)

MySQL手册在operator precedence上有一个页面。它表明AND具有更高的优先级。因此p1 AND p2 OR p3被解释为(p1 AND p2) OR p3。真值表很容易让你相信这与p1 AND (p2 OR p3)不同。

答案 4 :(得分:1)

关于SQL并不特别,它是关于布尔逻辑的。 您的第一个陈述是:

a AND b OR c

这意味着如果任何c为真,你就会获得该行。

在AND(b OR c)中

只能获得a为真且(b或c)为真的行。

答案 5 :(得分:1)

添加括号时,您正在更改条件。

在初始情况下,结果集包含满足条件的记录

`date_next_payment` <= '2011-02-02' AND `status` = 'active' 

或条件

 `status` = 'past due'.

添加括号后,结果集将包含满足条件的记录

`date_next_payment` <= '2011-02-02' 

和任何条件

`status` = 'active' 

`status` = 'past due'

答案 6 :(得分:0)

在您的第一个查询中 status ='有效'是条件为假,然后未评估下一个状态列条件(status

在您的第二个查询中

  

括号()具有高优先级

。所以(status ='有效'或status ='过期')条件首先进行评估。

答案 7 :(得分:0)

这是因为当你没有使用括号时,实际上是在说:

`date_next_payment` <= '2011-02-02'     AND `status` = 'active'
OR
`status` = 'past due'.

这意味着当status` ='逾期'时,也会显示此记录。不顾其他条件。

但是当你使用括号时,你需要:

 `date_next_payment` <= '2011-02-02'

并传递其他两个条件之一。