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

dre*_*joh 16 mysql sql

我有这个问题:

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

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

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

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

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

Pét*_*rök 26

这是因为OR的运算符优先级低于AND.每当DB看到类似的表达式时

A AND B OR C
Run Code Online (Sandbox Code Playgroud)

首先评估AND,即它等价于

(A AND B) OR C
Run Code Online (Sandbox Code Playgroud)

所以,如果你明确想要

A AND (B OR C)
Run Code Online (Sandbox Code Playgroud)

相反,你必须放入括号.

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


Fen*_*ton 5

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

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

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')
Run Code Online (Sandbox Code Playgroud)

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

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')
Run Code Online (Sandbox Code Playgroud)

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

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND (TRUE OR FALSE)
Run Code Online (Sandbox Code Playgroud)

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

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND TRUE
Run Code Online (Sandbox Code Playgroud)

日期是2011-01-01

SELECT * FROM (`users`) WHERE TRUE
AND TRUE
Run Code Online (Sandbox Code Playgroud)

最后,TRUE AND TRUE == TRUE

SELECT * FROM (`users`) WHERE TRUE
Run Code Online (Sandbox Code Playgroud)

所以记录被退回......

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