MySQL SELECT IF MAX: неожиданное поведение - PullRequest
0 голосов
/ 14 января 2020

У меня есть таблица 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.

Чего мне не хватает ??

Ответы [ 4 ]

3 голосов
/ 14 января 2020

У вас очевидно есть ноль строк.

Когда вы используете агрегатную функцию, такую ​​как MAX () или COUNT (), запрос вернет хотя бы одну строку, даже если в таблице есть ноль строк.

MAX(id) возвращает значение NULL, если в наборе строк, которые он просматривает, нет ненулевых значений идентификатора. Если у вас ноль строк, возвращается NULL.

NULL = NULL не возвращает true, возвращается NULL.

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

IF(NULL, 'true', 'false') возвращает false.

Возможно, вы захотите прочитать о нулевом безопасном операторе равенства .

mysql> select null <=> null;
+---------------+
| null <=> null |
+---------------+
|             1 |
+---------------+
1 голос
/ 14 января 2020

Некоторые заблуждения, которые я замечаю:

  • 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. Если таблица пуста, она не будет go и получит текущее значение AUTO_INCREMENT из определения таблицы, она просто вернет NULL , как задокументировано :

    Если совпадений нет строк, MAX() возвращает NULL.

  • IF () на самом деле здесь не играют никакой роли, но:

    Если expr1 равно TRUE (expr1 <> 0 и expr1 <> NULL), IF() возвращает expr2. В противном случае он возвращает expr3.

    (Это описание на самом деле вводит в заблуждение, потому что expr1 <> NULL фактически означает то, что предлагает обычный Engli sh.)

1 голос
/ 14 января 2020

Ваша таблица кажется пустой:

  • MAX(id) возвращает NULL; id является первичным ключом таблицы, поэтому он не может быть NULL, поэтому этот результат указывает на то, что в таблице вообще нет записей
  • IF(MAX(id), 'true', 'false') дает значение false, поскольку NULL является логически ложным
  • IF(MAX(id) = NULL, 'true', 'false') неверно, потому что NULL не равно NULL (чтобы проверить NULL, вам нужно IS NULL)
  • IF(!MAX(id), 'true', 'false') неверно, потому что ! NULL логически ложно

Вместо этого вы можете попробовать следующее выражение, которое должно дать 'true'

IF(MAX(id) IS NULL, 'true', 'false')
1 голос
/ 14 января 2020

Во всех этих случаях MAX(id) возвращает NULL, также !MAX(id) равно !NULL, что снова равно NULL. Булево выражение, которое NULL равно , а не TRUE, поэтому во всех первых 3 запросах результатом является FALSE часть функции IF().

...