Where 子句中的奇怪括号行为

Odd parentheses behavior in Where clause

设置:

MySQL 5.7.14 (Google SQL)

描述:

在下面的场景中,我似乎在没有使用括号的 where 子句中得到了一些错误匹配。但是添加括号确实会产生正确的结果。

此查询 return 结果 tsd.StatusID = 3 (错误):

SELECT 
tsee.ID, tsd.StatusID

FROM TSShiftDetails tsd
JOIN TSShiftEmployees tse
    ON tse.ShiftID = tsd.ID
JOIN TSShiftEmpEntries tsee
    ON tsee.ShiftEmpID = tse.ID

WHERE tsee.CCID IN (4590) OR tsee.CCID LIKE null
AND tsd.StatusID != 3

虽然此查询不会 return 结果为 AND tsd.StatusID = 3 (正确):

SELECT 
tsee.ID, tsd.StatusID

FROM TSShiftDetails tsd
JOIN TSShiftEmployees tse
    ON tse.ShiftID = tsd.ID
JOIN TSShiftEmpEntries tsee
    ON tsee.ShiftEmpID = tse.ID

WHERE (tsee.CCID IN (4590) OR tsee.CCID LIKE null)
AND tsd.StatusID != 3

问题:

虽然我觉得我完全理解为什么带括号的查询有效。我的问题是为什么没有括号 returning 记录的 StatusID == 3?我认为如果没有任何括号的功能排序,AND tsd.StatusID != 3 子句将应用于每个匹配项,而不管前面的 OR.

你会怎么想?我是误会了,还是 MySQL 在这里表现不一致?

P.S.

仅供参考,是的,前端应用程序需要以这种方式格式化 Where 子句。例如。 tsee.CCID IN (4590) 相对于 tsee.CCID =4590

解释与LIKE NULLIN ( )无关。

布尔表达式遵循运算符优先顺序,就像算术一样。

在算术中,你可能还记得乘法比加法有更高的优先级:

A + B * C

没有括号,这完全像:

A + (B * C)

如果要先计算加法,则必须使用括号来覆盖默认的运算符优先级:

(A + B) * C

同样,在布尔表达式中,AND的优先级高于OR

A OR B AND C

工作方式如下:

A OR (B AND C)

如果要先计算 OR,则必须使用括号来覆盖默认的运算符优先级:

(A OR B) AND C

这如何解释您所看到的?

WHERE tsee.CCID IN (4590) OR tsee.CCID LIKE null
AND tsd.StatusID != 3

这就像您完成的一样:

WHERE tsee.CCID IN (4590) OR (tsee.CCID LIKE null
AND tsd.StatusID != 3)

因此,如果它找到 CCID 为 4590 的行,则该行满足整个 WHERE 子句,因为 true OR (anything) 仍然为真。