Как Left Join / IS NULL устраняет записи, которые есть в одной таблице и нет в другой?



Мне трудно понять, почему это происходит.LEFT JOIN / IS NULL исключите записи, которые находятся в одной таблице, а не в другой.
Вот пример



SELECT  l.id, l.value
FROM t_left l
LEFT JOIN t_right r
ON r.value = l.value
WHERE r.value IS NULL


Зачем r.value = NULL уничтожать записи ? Я ничего не понимаю . Я знаю, что упускаю что-то очень основное, но в настоящее время я не могу понять даже это основное. Я был бы признателен, если бы кто-нибудь объяснил мне это подробно .



Мне нужно очень простое объяснение.
3022   11  

11 ответов:

Это можно объяснить следующим образом

mysql> select * from table1 ;
+------+------+
| id   | val  |
+------+------+
|    1 |   10 |
|    2 |   30 |
|    3 |   40 |
+------+------+
3 rows in set (0.00 sec)

mysql> select * from table2 ;
+------+------+
| id   | t1id |
+------+------+
|    1 |    1 |
|    2 |    2 |
+------+------+
2 rows in set (0.00 sec)

Здесь table1.id <-> table2.t1id

Теперь, когда мы делаем left join с ключом соединения, и если левая таблица-table1, то она получит все данные из table1 и в несоответствующей записи на table2 будет установлено значение null

mysql> select t1.* , t2.t1id from table1 t1 
left join table2 t2 on t2.t1id = t1.id ;
+------+------+------+
| id   | val  | t1id |
+------+------+------+
|    1 |   10 |    1 |
|    2 |   30 |    2 |
|    3 |   40 | NULL |
+------+------+------+

3 rows in set (0.00 sec)

Смотрите, что table1.id = 3 не имеет значения в таблице 2, поэтому его значение равно null Когда вы применяете условие where, оно будет выполнять дальнейшую фильтрацию

mysql> select t1.* , t2.t1id from table1 t1 
left join table2 t2 on t2.t1id = t1.id where t2.t1id is null;
+------+------+------+
| id   | val  | t1id |
+------+------+------+
|    3 |   40 | NULL |
+------+------+------+
1 row in set (0.00 sec)

Предположим, что r-таблица-это сотрудники, а r_table-компьютеры. У некоторых сотрудников нет компьютеров. Некоторые компьютеры еще никому не назначены.

  1. Внутреннее соединение:

    SELECT  l.*, r.*
    FROM    employees l
    JOIN computers r
    ON      r.id = l.comp_id
    

    Дает вам список всех сотрудников, у которых есть компьютер, и информацию о компьютере, назначенном для каждого из них. Сотрудники без компьютера в этом списке не появятся.

  2. Левое соединение:

    SELECT  l.*, r.*
    FROM    employees l
    LEFT JOIN computers r
    ON      r.id = l.comp_id
    

    Дает вам список всех сотрудников. Сотрудники с компьютером покажет информацию о компьютере. Сотрудники без компьютеров будут появляться с нулями вместо информации о компьютере.

  3. Наконец

    SELECT  l.*, r.*
    FROM    employees l
    LEFT JOIN computers r
    ON      r.id = l.comp_id
    WHERE   r.id IS NULL
    

    Левое соединение с предложением WHERE будет начинаться с того же списка, что и левое соединение (2), но тогда он будет держать только тех сотрудников, которые не имеют соответствующей информации в компьютерной таблице, то есть сотрудников без компьютеров.

    В этом случае выбор чего-либо из таблицы r будет просто равен нулю, поэтому вы можно оставить эти поля и выбрать только материал из таблицы l:

    SELECT  l.*
    FROM ...
    

Попробуйте выполнить эту последовательность выборок и понаблюдайте за выводом. Каждый следующий шаг основывается на предыдущем.

Пожалуйста, дайте мне знать, если это объяснение понятно, или вы хотите, чтобы я уточнил еще немного.

ОТРЕДАКТИРОВАНО ДЛЯ ДОБАВЛЕНИЯ: Вот пример кода для создания двух таблиц, используемых выше:

CREATE TABLE employees
(  id INT NOT NULL PRIMARY KEY,
   name VARCHAR(20),
   comp_id INT);

INSERT INTO employees (id, name, comp_id) VALUES (1, 'Becky', 1);
INSERT INTO employees (id, name, comp_id) VALUES (2, 'Anne', 7);
INSERT INTO employees (id, name, comp_id) VALUES (3, 'John', 3);
INSERT INTO employees (id, name) VALUES (4, 'Bob');

CREATE TABLE computers
(  id INT NOT NULL PRIMARY KEY,
   os VARCHAR(20) );

INSERT INTO computers (id, os) VALUES (1,'Windows 7');
INSERT INTO computers (id, os) VALUES (2,'Windows XP');
INSERT INTO computers (id, os) VALUES (3,'Unix');
INSERT INTO computers (id, os) VALUES (4,'Windows 7');
Есть 4 сотрудника. У Бекки и Джона есть компьютеры. У Энн и Боба нет компьютера. (У Энн есть comp_id 7, который не соответствует ни одной строке в таблице computers - значит, у нее на самом деле нет компьютера.)

Левая возвращает всю строку из левой таблицы

На r. value = l. value
если для значения l нет значения r, то r пуст
r. значение null будет истинно

В вашем примере результатом будет каждая запись из t_left, а также каждая соответствующая запись из t_right, где они оба имеют одинаковый value. там, где нет совпадения, вместо значений из t_right задаются значения NULL. where r.value is null просто удаляет совпадающие строки, обнаруживая эти значения null.

По существу говоря ' дайте мне строки из t_left , которые не соответствуют строкам в t_right

A right join выполняет обратный порядок left join.

Это основано на разнице между INNER JOIN и LEFT JOIN. При использовании INNER JOIN результат содержит только строки, соответствующие двум таблицам (на основе условия ON).

Но когда вы используете LEFT JOIN, вы также получаете строки в результате для всех строк в первой таблице, которые не имеют совпадения во второй таблице. В этих случаях все результирующие столбцы из второй таблицы заполняются NULL в качестве заполнителя.

Тест WHERE r.value IS NULL затем соответствует этим строкам. Так конечный результат содержит только строки без совпадений.

Left JOIN принимает значения слева и пытается сопоставить таблицу слева по столбцу, указанному на ON если он не находит соответствия, то он интерпретирует столбцы правой таблицы как NULL. следовательно, только те, которые не могут найти совпадение в правой таблице, будут выбраны оператором IS NULL

Во-первых, левое соединение утверждает, что все записи из левой таблицы будут включены, и только те из правой, которые совпадают.

Итак, допустим, у вас есть red, blue и green носок в вашем ящике, а ваш друг только red, yellow и blue, левое соединение из вашего ящика к вашим друзьям вернет все носки из вашего ящика (red, blue и green) и только совпадающие из ваших друзей (red и blue).

Теперь нулевая часть говорит, что вы хотите видеть все носки из вашего ящика, где нет подходящих пар партнеров в ящике ваших друзей, поэтому из всех ваших носков единственный с отсутствующей парой-это носок green.

Это предложение:

SELECT  l.id, l.value
FROM    t_left l
LEFT JOIN t_right r
ON      r.value = l.value

Будет иметь все элементы из таблицы t_left, присоединенные ко всем элементам из таблицы t_right. Как вы, вероятно, и сделаете сейчас, в INNER JOIN будут показаны только строки, соответствующие обеим таблицам, так чтоt_left может иметь меньше строк , чем все возможные строки. В LEFT JOIN, у вас есть все строки из t_left таблицы плюс соответствующие строки из t_right (если они могут быть объединены). Итак, что происходит со строками в t_left, которые не соответствуют ни одной строке t_right? Все поля из t_right таблица, которая должна была бы содержать данные, будет заполнена нулевыми значениями. Таким образом, если вы выберете только значения NULL из правой таблицы, вы найдете все значения из таблицы t_left, которые не совпадают с правой, XD

Left join дает все записи из левой таблицы. Если какой-либо ключ, присутствующий в левой таблице, отсутствует в правой таблице, то все столбцы правой таблицы будут иметь значение null, но все значения левой таблицы будут присутствовать.

Это основное различие между внутренним соединением и левым / правым соединением.

Таким образом, когда вы делаете 'r.value = null`, вы получаете те записи слева, где в правой таблице нет соответствующего ключа.

HTH.

Это просто левый join funda..... следующий запрос получает всю запись из левой таблицы и сопоставленную запись из правой таблицы, если она не совпадает, то возвращает NUll Значение. в конце вы фильтруете данные, используя условие where, которое возвращает значения, которые находятся в левой таблице, но не в правой таблице

 SELECT  l.id, l.value
    FROM    t_left l
    LEFT JOIN t_right r
    ON      r.value = l.value
    WHERE   r.value IS NULL
 SELECT * FROM a LEFT JOIN b ON a.v = b.v ... WHERE b.id IS NULL

Это супер простая логика:

  • Выберите из таблицы " a "
  • соедините таблицу "b" (если совпадающие строки существуют-на a. v=b. v в противном случае используйте NULL в качестве значений)
  • , где условие: если чего-то не хватает (б.идентификатор имеет значение null) = ОК.

Comments

    Ничего не найдено.