smi*_*hax 5 mysql sql sqlite postgresql mariadb
为什么大多数(全部?)SQL 数据库给出:
SELECT FALSE < FALSE; -- FALSE / 0 Ok
SELECT TRUE < FALSE; -- FALSE / 0 Ok
SELECT NOT(FALSE) < FALSE; -- TRUE / 1 What?
SELECT NOT(TRUE) < FALSE; -- TRUE / 1 What??
Run Code Online (Sandbox Code Playgroud)
只需仔细检查即可:
SELECT NOT(TRUE) = FALSE; -- TRUE / 1 Ok
SELECT NOT(FALSE) = TRUE; -- TRUE / 1 Ok
Run Code Online (Sandbox Code Playgroud)
在 Postgres 中,我还可以检查:
SELECT pg_typeof(TRUE), pg_typeof(NOT(FALSE));
-- boolean | boolean
Run Code Online (Sandbox Code Playgroud)
我已经在 PostgreSQL、SQLite3 和 MariaDB 上尝试过这一点,并且都同意相同的意外结果。
我缺少什么?
NOT和<是运营商。让我们看一下运算符优先级:
https://dev.mysql.com/doc/refman/8.0/en/operator-precedence.html
从这里我们可以看到<优先级NOT优先,所以
NOT(FALSE) < FALSE
Run Code Online (Sandbox Code Playgroud)
相当于
NOT(FALSE < FALSE)
Run Code Online (Sandbox Code Playgroud)
自从FALSE不小于自身,因此内部表达式为 0,即 it'sFALSE且其否定为TRUE。
然而,如果您强制执行您希望的操作员命令:
(NOT(FALSE)) < FALSE
Run Code Online (Sandbox Code Playgroud)
然后你会得到你期望的结果:
我不知道具体NOT(FALSE)是如何评估的,但NOT它不是一个函数。如果您不想使用布尔文字,那么括号应该放在整个表达式周围,即使用(NOT FALSE)而不是NOT(FALSE)。考虑:
SELECT (NOT FALSE) < FALSE; -- 0, same as TRUE < FALSE
SELECT (NOT TRUE) < FALSE; -- 0, same as FALSE < FALSE
Run Code Online (Sandbox Code Playgroud)
我的答案是关于 SQLite (但我怀疑这同样适用于其他数据库)。
像这样的表达式:
NOT(FALSE) < FALSE;
Run Code Online (Sandbox Code Playgroud)
被评估为:
NOT((FALSE) < FALSE);
Run Code Online (Sandbox Code Playgroud)
因为运算符 的<优先级高于 运算符NOT。
由于(FALSE) < FALSE计算结果为FALSE,因此表达式的结果为TRUE。
| 归档时间: |
|
| 查看次数: |
106 次 |
| 最近记录: |