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)returnsNULLid是table的主键所以不可能是NULL,所以这个结果说明table
  • 中根本没有记录
  • IF(MAX(id), 'true', 'false') 产生 false 因为 NULL 在逻辑上是 false
  • IF(MAX(id) = NULL, 'true', 'false') 为假,因为 NULL 不等于 NULL(要检查 NULLness,您需要 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 实际上是普通英语所暗示的意思。)