【问题标题】:MySQL SELECT IF MAX: unexpected behaviourMySQL SELECT IF MAX:意外行为
【发布时间】:2020-01-14 17:05:57
【问题描述】:

我有一个没有记录的 MySQL 表。

-- 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

我错过了什么?

【问题讨论】:

  • 是的,我以前做过。为什么SELECT IF(MAX(id) = NULL, 'true', 'false') FROM 'vcr_grades'我没有记录却返回false?
  • AUTO_INCREMENT 总是增加,所以你不会与ids 发生冲突。如果您删除然后重用以前的id,您可能与其他表的映射不正确。不确定这是否能回答您的问题。你在这里问什么?
  • 对 null 的测试是 IS NULL not = null。

标签: mysql sql database group-by sql-null


【解决方案1】:

你显然有零行。

当您使用 MAX() 或 COUNT() 之类的聚合函数时,查询将返回至少一行,即使该表有零行。

MAX(id) 如果在它扫描的行集中没有非 NULL id 值,则返回 NULL。如果你有零行,这将返回 NULL。

NULL = NULL 不返回 true,它返回 NULL。

mysql> select null=null;
+-----------+
| null=null |
+-----------+
|      NULL |
+-----------+

IF(NULL, 'true', 'false') 返回“假”。

您可能想了解null-safe equal operator

mysql> select null <=> null;
+---------------+
| null <=> null |
+---------------+
|             1 |
+---------------+

【讨论】:

  • 我必须阅读有关 MySQL 运算符的信息,我对此一无所知。谢谢你的澄清:)
【解决方案2】:

在所有这些情况下,MAX(id) 返回 NULL!MAX(id) 也是 !NULL,这又是 NULL
NULL 的布尔表达式 not TRUE 因此在所有前 3 个查询中,结果是函数 IF()FALSE 部分。

【讨论】:

    【解决方案3】:

    您的桌子似乎是空的:

    • MAX(id) 返回NULLid是表的主键,所以不能是NULL,所以这个结果说明表中根本没有记录
    • IF(MAX(id), 'true', 'false') 产生错误,因为 NULL 在逻辑上是错误的
    • 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')
    

    【讨论】:

      【解决方案4】:

      我发现的一些误解:

      • 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 功能只不过是一个全局计数器,可用于生成唯一的不可重用的表范围整数。它通常用于填充主键这一事实并不能使其成为主键的同义词。

      • MAX(id) 完全按照其名称所暗示的那样做:获取id 列中的最大值。如果表是空的,它不会去从表定义中获取当前的 AUTO_INCREMENT 值,它只会返回 NULL as documented

        如果没有匹配的行,MAX() 返回NULL

      • IF() 在这里并没有真正发挥任何作用,但是:

        如果expr1TRUEexpr1 &lt;&gt; 0expr1 &lt;&gt; NULL),则IF() 返回expr2。否则,它返回expr3

        (这种描述实际上具有误导性,因为expr1 &lt;&gt; NULL 实际上意味着简单的英语所暗示的内容。)

      【讨论】:

        猜你喜欢
        • 2021-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多