MySQL оставил соединение: нулевые элементы будут отфильтрованы по - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть 2 таблицы MySQL: join_test_l и join_test_r.

join_test_l:

+------+------+
| ca   | cb   |
+------+------+
| a    | s    |
| b    | s    |
| c    | d    |
| d    | NULL |
+------+------+

join_test_r:

+------+------+
| cc   | cb   |
+------+------+
| a    | NULL |
| b    | s    |
| c    | d    |
| d    | NULL |
+------+------+

и когда я пытался выполнить запрос с левым соединением и <> фильтром в левой таблице:

select * from join_test_l as l left join join_test_r as r on l.cb=r.cb where l.ca<>'c';
+------+------+------+------+
| ca   | cb   | cc   | cb   |
+------+------+------+------+
| a    | s    | b    | s    |
| b    | s    | b    | s    |
| d    | NULL | NULL | NULL |
+------+------+------+------+

строкгде l.ca равно null осталось.и когда я попытался выполнить запрос с левым соединением и <> фильтром в правой таблице:

select * from join_test_l as l left join join_test_r as r on l.cb=r.cb where r.cc<>'c';
+------+------+------+------+
| ca   | cb   | cc   | cb   |
+------+------+------+------+
| a    | s    | b    | s    |
| b    | s    | b    | s    |
+------+------+------+------+

все строки, где r.cc равен null, также удаляются.

Кто-нибудь может объяснить это?Я имею в виду, почему нулевые значения в наборе результатов фильтруются предложением <>?

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Re <> & null

x<>y равно true, когда x не равно (в обычном смысле) y and x is not null and y is not null. Это false, когда x равно (в обычном смысле) y and x is not null and y is not null. В противном случае это технически unknown, но это обрабатывается так, как если бы оно было null операторами / синтаксисом вроде is.

Большинство операторов SQL такие - они возвращают свои нормальные результаты, когда каждый аргумент is not null и unknown (обрабатываются как null) в противном случае. Операторы SQL не являются обычными реляционными или математическими операторами с одинаковыми именами; они относятся (значения) unknown & null специально. (Сказать, что null не является значением, - нечеткая бесполезная риторика культуры SQL.)

Re "нормальное чувство равенства" из Справочного руководства по MySQL 8.0 12.3.2 Функции сравнения и операторы :

Операции сравнения приводят к значению 1 (TRUE), 0 (FALSE) или NULL.

  • <=>

    NULL -безопасно равно. Этот оператор выполняет сравнение на равенство, как оператор =, но возвращает 1 вместо NULL, если оба операнда NULL, и 0 вместо NULL, если один операнд NULL. Оператор <=> эквивалентен стандартному оператору SQL IS NOT DISTINCT FROM.

Примечание on & where возвращает строки, для которых условие оценивается как true. Ограничения удовлетворяются, когда они не оцениваются в false.

Re left join on & where

Узнайте, что возвращает LEFT / RIGHT JOIN: строки INNER JOIN плюс несопоставленные строки таблицы слева / справа, расширенные значениями NULL. FULL JOIN возвращает строки INNER JOIN UNION ВСЕ несоответствующие строки таблицы слева и справа, расширенные значениями NULL. Всегда знайте, какое ВНУТРЕННЕЕ СОЕДИНЕНИЕ вы хотите как часть ВНЕШНЕГО СОЕДИНЕНИЯ WHERE или ON, которые требуют, чтобы столбец, возможно расширенный NULL, не был NULL после того, как OUTER JOIN ON удаляет все строки, расширенные NULL, т.е. оставляет только строки INNER JOIN, т.е. «превращает OUTER JOIN в INNER JOIN». У вас есть это.

Прочитайте документацию по СУБД SQL.

0 голосов
/ 08 ноября 2018

Вам необходимо переместить логику в предложении WHERE в предложение ON:

SELECT *
FROM join_test_l as l
LEFT JOIN join_test_r as r
    ON l.cb = r.cb AND r.cc <> 'c';

Проблема в том, что WHERE отфильтровывает записи из набора результатов. С другой стороны, перемещая логику в объединение, мы сохраняем каждую запись в левой таблице join_test_l. Тогда записи, которые ни к чему не присоединяются, будут иметь null для каждого столбца в join_test_r.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...