mariadb 布尔值之间的SQL little/great比较会产生意外结果

bttbmeg0  于 2023-10-20  发布在  其他
关注(0)|答案(3)|浏览(169)

为什么大多数(所有?)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??

然后再仔细检查一下:

SELECT NOT(TRUE) = FALSE;  -- TRUE / 1    Ok
SELECT NOT(FALSE) = TRUE;  -- TRUE / 1    Ok

在Postgres中,我还可以检查:

SELECT pg_typeof(TRUE), pg_typeof(NOT(FALSE));
  -- boolean | boolean

我已经在PostgreSQL、SQLite3和MariaDB上尝试过了这一点,所有人都同意相同的意想不到的结果。

我错过了什么?

pjngdqdw

pjngdqdw1#

NOT<是运算符。让我们来看看运算符优先级:

https://dev.mysql.com/doc/refman/8.0/en/operator-precedence.html
从这里我们可以看到<的优先级在NOT之前,所以

NOT(FALSE) < FALSE

相当于

NOT(FALSE < FALSE)

因为FALSE不小于它本身,所以内部表达式为0,也就是说,它是FALSE,它的否定式是TRUE
然而,如果您强制执行您喜欢的操作符顺序:

(NOT(FALSE)) < FALSE

你会得到你所期望的结果:

3htmauhk

3htmauhk2#

我不知道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
kfgdxczn

kfgdxczn3#

我的答案是关于SQLite的(但我怀疑这同样适用于其他数据库)。
类似于以下的表达式:

NOT(FALSE) < FALSE;

评价为:

NOT((FALSE) < FALSE);

因为运算符<具有高于运算符NOT的优先级。
由于(FALSE) < FALSE的计算结果为FALSE,因此表达式的结果为TRUE

相关问题