Почему 0 результатов в том месте, где нет запроса

mysql> show columns in m like 'fld';
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| fld   | varchar(45) | YES  | MUL | NULL    |       |
+-------+-------------+------+-----+---------+-------+
1 row in set (0.02 sec)

mysql> show columns in i like 'fld';
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| fld   | varchar(45) | YES  | MUL | NULL    |       |
+-------+-------------+------+-----+---------+-------+
1 row in set (0.02 sec)

mysql> select count(distinct fld) from i;
+---------------------+
| count(distinct fld) |
+---------------------+
|               27988 |
+---------------------+
1 row in set (0.03 sec)

mysql> select count(distinct fld) from m;
+---------------------+
| count(distinct fld) |
+---------------------+
|               72558 |
+---------------------+
1 row in set (0.07 sec)

Приведенные выше результаты кажутся разумными на основе того, что я знаю о рассматриваемых таблицах.

mysql> select count(*) from m where fld not in (select fld from i);
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.11 sec)

Последний результат не кажется разумным. Должно быть несколько строк в m, где fld не в i! Может кто-нибудь объяснить, почему я получаю 0 в результате?


Для полноты (поскольку я подозреваю, что это может быть актуально) я также вставлю этот результат:

mysql> select count(*) from m where fld is null;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

Изменить: отвечая на комментарии, я также редактирую следующую информацию, если это поможет кому-то ответить на мой вопрос:

  • select count(*) from m join i using (fld) дает 9350; с left join, 73087; с right join, 28872.
  • select count(*) from i where fld is null дает 810.

person JQKP    schedule 12.05.2015    source источник


Ответы (1)


Я сейчас в этом разобрался. В документации говорится:

В соответствии со стандартом SQL IN возвращает NULL не только в том случае, если выражение в левой части равно NULL, но также, если в списке не найдено совпадений и одно из выражений в списке - NULL.

Таким образом, fld not in (т.е. not fld in) возвращает not null (т.е. null) всякий раз, когда в производной таблице (которая есть здесь) есть null, а fld не обнаруживается в производной таблице (это то, что я тестирую).


Возможно, есть способ лучше, чем этот, но я использую (select fld from i where fld is not null).

person JQKP    schedule 12.05.2015
comment
Истинный. Странное поведение. Может быть, для этого есть веская причина, но пока я видел только ошибки из-за этого, а никаких преимуществ. Кстати, это не только в MySQL. - person GolezTrol; 13.05.2015