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 NULL
或IN ( )
无关。
布尔表达式遵循运算符优先顺序,就像算术一样。
在算术中,你可能还记得乘法比加法有更高的优先级:
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)
仍然为真。
设置:
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 NULL
或IN ( )
无关。
布尔表达式遵循运算符优先顺序,就像算术一样。
在算术中,你可能还记得乘法比加法有更高的优先级:
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)
仍然为真。