MySQL SELECT IF MAX:意外行为
MySQL SELECT IF MAX: unexpected behaviour
我有一个 MySQL table 里面没有记录。
-- all of these return false
SELECT IF(MAX(id), 'true', 'false') FROM `vcr_grades`
SELECT IF(MAX(id) = NULL, 'true', 'false') FROM `vcr_grades`
SELECT IF(!MAX(id), 'true', 'false') FROM `vcr_grades`
-- returns NULL
SELECT MAX(id) FROM `vcr_grades`
AUTO_INCREMENT
设置为不同于 1
的另一个值。主键是 id
.
我错过了什么??
您显然有零行。
当您使用像 MAX() 或 COUNT() 这样的聚合函数时,查询将 return 至少一行,即使 table 有零行。
MAX(id)
returns NULL 如果在它扫描的行集中没有非 NULL id 值。如果你有零行,这将 return NULL。
NULL = NULL
不 return 正确,它 return 是 NULL。
mysql> select null=null;
+-----------+
| null=null |
+-----------+
| NULL |
+-----------+
IF(NULL, 'true', 'false')
returns 'false'.
您可能想阅读有关 null-safe equal operator 的内容。
mysql> select null <=> null;
+---------------+
| null <=> null |
+---------------+
| 1 |
+---------------+
在所有这些情况下 MAX(id)
returns NULL
,而且 !MAX(id)
是 !NULL
又是 NULL
.
NULL
的布尔表达式是 而不是 TRUE
因此在所有前 3 个查询中,结果是函数 FALSE
的一部分 IF()
.
您的 table 似乎是空的:
MAX(id)
returnsNULL
; id
是table的主键所以不可能是NULL
,所以这个结果说明table 中根本没有记录
IF(MAX(id), 'true', 'false')
产生 false 因为 NULL
在逻辑上是 false
IF(MAX(id) = NULL, 'true', 'false')
为假,因为 NULL
不等于 NULL
(要检查 NULL
ness,您需要 IS NULL
)
IF(!MAX(id), 'true', 'false')
是假的,因为 ! NULL
在逻辑上是假的
您可以试试下面的表达式,它应该会产生 'true'
IF(MAX(id) IS NULL, 'true', 'false')
我发现的一些误解:
NULL
与其他任何事物既不相等也不不同......包括它自己:
mysql> SELECT 1 = 1, 1 <> 1, 1 = NULL, 1 <> NULL, NULL = NULL, NULL <> NULL;
+-------+--------+----------+-----------+-------------+--------------+
| 1 = 1 | 1 <> 1 | 1 = NULL | 1 <> NULL | NULL = NULL | NULL <> NULL |
+-------+--------+----------+-----------+-------------+--------------+
| 1 | 0 | NULL | NULL | NULL | NULL |
+-------+--------+----------+-----------+-------------+--------------+
1 row in set (0.00 sec)
这就是我们使用 IS
运算符的原因,如:
mysql> SELECT 1 IS NULL, 1 IS NOT NULL, NULL IS NULL, NULL IS NOT NULL;
+-----------+---------------+--------------+------------------+
| 1 IS NULL | 1 IS NOT NULL | NULL IS NULL | NULL IS NOT NULL |
+-----------+---------------+--------------+------------------+
| 0 | 1 | 1 | 0 |
+-----------+---------------+--------------+------------------+
1 row in set (0.00 sec)
AUTO_INCREMENT
功能不过是一个全局计数器,您可以使用它来生成唯一不可重复使用的 table 范围内的整数。它通常用于填充主键这一事实并不能使它成为主键的同义词。
MAX(id)
完全按照名称的含义进行操作:获取列 id
中的最大值。如果 table 为空,它不会从 table 定义中获取当前 AUTO_INCREMENT 值,它只会 return NULL
as documented:
If there are no matching rows, MAX()
returns NULL
.
IF()在这里没有真正发挥任何作用但是:
If expr1
is TRUE
(expr1 <> 0
and expr1 <> NULL
), IF()
returns expr2
. Otherwise, it returns expr3
.
(此描述实际上具有误导性,因为 expr1 <> NULL
实际上是普通英语所暗示的意思。)
我有一个 MySQL table 里面没有记录。
-- all of these return false
SELECT IF(MAX(id), 'true', 'false') FROM `vcr_grades`
SELECT IF(MAX(id) = NULL, 'true', 'false') FROM `vcr_grades`
SELECT IF(!MAX(id), 'true', 'false') FROM `vcr_grades`
-- returns NULL
SELECT MAX(id) FROM `vcr_grades`
AUTO_INCREMENT
设置为不同于 1
的另一个值。主键是 id
.
我错过了什么??
您显然有零行。
当您使用像 MAX() 或 COUNT() 这样的聚合函数时,查询将 return 至少一行,即使 table 有零行。
MAX(id)
returns NULL 如果在它扫描的行集中没有非 NULL id 值。如果你有零行,这将 return NULL。
NULL = NULL
不 return 正确,它 return 是 NULL。
mysql> select null=null;
+-----------+
| null=null |
+-----------+
| NULL |
+-----------+
IF(NULL, 'true', 'false')
returns 'false'.
您可能想阅读有关 null-safe equal operator 的内容。
mysql> select null <=> null;
+---------------+
| null <=> null |
+---------------+
| 1 |
+---------------+
在所有这些情况下 MAX(id)
returns NULL
,而且 !MAX(id)
是 !NULL
又是 NULL
.
NULL
的布尔表达式是 而不是 TRUE
因此在所有前 3 个查询中,结果是函数 FALSE
的一部分 IF()
.
您的 table 似乎是空的:
MAX(id)
returnsNULL
;id
是table的主键所以不可能是NULL
,所以这个结果说明table 中根本没有记录
IF(MAX(id), 'true', 'false')
产生 false 因为NULL
在逻辑上是 falseIF(MAX(id) = NULL, 'true', 'false')
为假,因为NULL
不等于NULL
(要检查NULL
ness,您需要IS NULL
)IF(!MAX(id), 'true', 'false')
是假的,因为! NULL
在逻辑上是假的
您可以试试下面的表达式,它应该会产生 'true'
IF(MAX(id) IS NULL, 'true', 'false')
我发现的一些误解:
NULL
与其他任何事物既不相等也不不同......包括它自己:mysql> SELECT 1 = 1, 1 <> 1, 1 = NULL, 1 <> NULL, NULL = NULL, NULL <> NULL; +-------+--------+----------+-----------+-------------+--------------+ | 1 = 1 | 1 <> 1 | 1 = NULL | 1 <> NULL | NULL = NULL | NULL <> NULL | +-------+--------+----------+-----------+-------------+--------------+ | 1 | 0 | NULL | NULL | NULL | NULL | +-------+--------+----------+-----------+-------------+--------------+ 1 row in set (0.00 sec)
这就是我们使用
IS
运算符的原因,如:mysql> SELECT 1 IS NULL, 1 IS NOT NULL, NULL IS NULL, NULL IS NOT NULL; +-----------+---------------+--------------+------------------+ | 1 IS NULL | 1 IS NOT NULL | NULL IS NULL | NULL IS NOT NULL | +-----------+---------------+--------------+------------------+ | 0 | 1 | 1 | 0 | +-----------+---------------+--------------+------------------+ 1 row in set (0.00 sec)
AUTO_INCREMENT
功能不过是一个全局计数器,您可以使用它来生成唯一不可重复使用的 table 范围内的整数。它通常用于填充主键这一事实并不能使它成为主键的同义词。MAX(id)
完全按照名称的含义进行操作:获取列id
中的最大值。如果 table 为空,它不会从 table 定义中获取当前 AUTO_INCREMENT 值,它只会 returnNULL
as documented:If there are no matching rows,
MAX()
returnsNULL
.IF()在这里没有真正发挥任何作用但是:
If
expr1
isTRUE
(expr1 <> 0
andexpr1 <> NULL
),IF()
returnsexpr2
. Otherwise, it returnsexpr3
.(此描述实际上具有误导性,因为
expr1 <> NULL
实际上是普通英语所暗示的意思。)