Mysql left join select примеры. Простые примеры JOIN

9.5K

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

Введение в LEFT JOIN MySQL

Оператор MySQL LEFT JOIN позволяет запрашивать данные из двух или более таблиц базы данных. Он является необязательной частью оператора SELECT , которая указывается после FROM .

Предположим, что вы собираетесь запрашивать данные из таблиц t1 и t2 . На примере приведенного ниже запроса мы проиллюстрируем синтаксис LEFT JOIN , объединяя две таблицы:

SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;

Когда вы подключаетесь к таблицам t1 и t2 , используя оператор LEFT JOIN , если строка из левой таблицы t1 соответствует строке из правой таблицы t2 на основе условия соединения (t1.c1 = t2.c1 ), эта строка будет включена в результирующий набор.

Если значение в левой таблице не соответствует значению в правой таблице, строка в левой таблице также выбирается и объединяется с «условной » строкой из правой таблицы. «Условная » строка содержит NULL для всех соответствующих столбцов в операторе SELECT .

Другими словами, условие MySQL LEFT JOIN позволяет выбирать строки обеих таблиц, которые совпадают, плюс все строки из левой таблицы (t1 ) даже без совпадения со строками правой таблицы (t2 ).

Следующая диаграмма поможет представить, как работает условие LEFT JOIN . Пересечение двух кругов — это строки, которые соответствуют в обеих таблицах, а оставшаяся часть левого круга — это строки в таблице t1 , которые не имеют соответствующей строки в таблице t2 . Следовательно, все строки в левой таблице включены в результирующий набор.


Обратите внимание, что возвращаемые значения также должны соответствовать условиям в операторах WHERE и HAVING , если эти операторы доступны в запросе. Примеры использования LEFT JOIN Использование оператора MySQL LEFT JOIN для объединения двух таблиц

Возьмем две таблицы клиентов и заказов из демонстрационной базы данных :


В базе данных, описанной на диаграмме:
  • Каждый заказ в таблице заказов должен принадлежать клиенту в таблице клиентов;
  • Каждый клиент в таблице клиентов может иметь ноль или более заказов в таблице заказов.

Чтобы найти заказы, принадлежащие каждому клиенту, можно использовать MySQL LEFT JOIN пример:

SELECT c.customerNumber, c.customerName, orderNumber, o.status FROM customers c LEFT JOIN orders o ON c.customerNumber = o.customerNumber

Посмотреть пример


Левая таблица — это клиенты, поэтому все клиенты включены в результирующий набор. Но в нем есть строки, которые имеют данные клиента, но не имеют данных заказа, например. 168, 169 и т. д. Данные заказов в этих строках равны NULL . Это означает, что у этих клиентов нет заказов в соответствующей таблице.

Поскольку мы использовали одно и то же имя столбца (orderNumber ) для объединения двух таблиц, можно сделать запрос короче, используя приведенный ниже синтаксис:

SELECT c.customerNumber, customerName, orderNumber, status FROM customers c LEFT JOIN orders USING (customerNumber);

Если вы замените оператор MySQL SELECT LEFT JOIN оператором INNER JOIN , вы получите только клиентов, которые оформили хотя бы один заказ.

Использование оператора MySQL LEFT JOIN для поиска несовпадающих строк

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

Например, чтобы найти всех клиентов, которые не оформили ни одного заказа, используется следующий запрос:

Посмотреть пример

Условие в операторе WHERE или условие в операторе ON

Рассмотрим следующий пример использования MySQL LEFT JOIN WHERE :

В этом примере мы использовали оператор LEFT JOIN для запроса данных из таблиц orders и orderDetails . Запрос возвращает заказ и его данные, если они есть, для заказа 10123.

MySQL поддерживает следующий синтаксис оператора JOIN при использовании в командах SELECT:

Table_reference, table_reference table_reference JOIN table_reference table_reference INNER JOIN table_reference join_condition table_reference STRAIGHT_JOIN table_reference table_reference LEFT JOIN table_reference join_condition table_reference LEFT JOIN table_reference table_reference NATURAL ] JOIN table_reference { oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr } table_reference RIGHT JOIN table_reference join_condition table_reference RIGHT JOIN table_reference table_reference NATURAL ] JOIN table_reference

где table_reference определено, как:

Table_name [ alias]

и join_condition определено, как:

ON conditional_expr | USING (column_list)

Никогда не следует указывать в части ON какие бы то ни было условия, накладывающие ограничения на строки в наборе результатов. Если необходимо указать, какие строки должны присутствовать в результате, следует сделать это в выражении WHERE .

Необходимо учитывать, что в версиях до 3.23.17 оператор INNER JOIN не принимает параметр join_condition !

Наличие последней из приведенных выше конструкций выражения LEFT OUTER JOIN обусловлено только требованиями совместимости с ODBC:

  • Вместо ссылки на таблицу может использоваться псевдоним, который присваивается при помощи выражений tbl_name AS alias_name или tbl_name alias_name: mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name;
  • Условный оператор ON представляет собой условие в любой форме из числа тех, которые можно использовать в выражении WHERE .
  • Если запись для правой таблицы в частях ON или USING в LEFT JOIN не найдена, то для данной таблицы используется строка, в которой все столбцы установлены в NULL . Эту возможность можно применять для нахождения результатов в таблице, не имеющей эквивалента в другой таблице: mysql> SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL; Этот пример находит все строки в таблице table1 с величиной id , которая не присутствует в таблице table2 (т.е. все строки в table1 , для которых нет соответствующих строк в table2). Конечно, это предполагает, что table2.id объявлен как NOT NULL . See section 5.2.6 Как MySQL оптимизирует LEFT JOIN и RIGHT JOIN .
  • USING (column_list) служит для указания списка столбцов, которые должны существовать в обеих таблицах. Такое выражение USING , как: A LEFT JOIN B USING (C1,C2,C3,...) семантически идентично выражению ON , например: A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
  • Выражение NATURAL JOIN для двух таблиц определяется так, чтобы оно являлось семантическим эквивалентом INNER JOIN или LEFT JOIN с выражением USING , в котором указаны все столбцы, имеющиеся в обеих таблицах.
  • INNER JOIN и, (запятая) являются семантическими эквивалентами. Оба осуществляют полное объединение используемых таблиц. Способ связывания таблиц обычно задается в условии WHERE .
  • RIGHT JOIN работает аналогично LEFT JOIN . Для сохранения переносимости кода между различными базами данных рекомендуется вместо RIGHT JOIN использовать LEFT JOIN .
  • STRAIGHT_JOIN идентично JOIN , за исключением того, что левая таблица всегда читается раньше правой. Это выражение может использоваться для тех (немногих) случаев, когда оптимизатор объединения располагает таблицы в неправильном порядке.
  • Начиная с версии MySQL 3.23.12, можно давать MySQL указания о том, какой индекс должен использоваться при извлечении информации из таблицы. Эта возможность полезна, если оператор EXPLAIN (выводящий информацию о структуре и порядке выполнения запроса SELECT), показывает, что MySQL использует ошибочный индекс. Задавая значение индекса в USE INDEX (key_list) , можно заставить MySQL применять для поиска записи только один из указанных индексов. Альтернативное выражение IGNORE INDEX (key_list) запрещает использование в MySQL данного конкретного индекса. Выражения USE/IGNORE KEY являются синонимами для USE/IGNORE INDEX .

Несколько примеров:

Mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id); mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id LEFT JOIN table3 ON table2.id=table3.id; mysql> SELECT * FROM table1 USE INDEX (key1,key2) WHERE key1=1 AND key2=2 AND key3=3; mysql> SELECT * FROM table1 IGNORE INDEX (key3) WHERE key1=1 AND key2=2 AND key3=3;

На протяжении немалого времени, в начале своей карьеры веб-разработчика, я работал с базой данный как умел, а умел я не многое. Составлял простые примитивные запросы, а порою даже вставлял запросы в циклы. На тот момент мне к сожалению не попалась в руки правильная книжка по mySQL и учить приходилось методом проб и ошибок. Множество статей в интернете как-то не сразу донесли до меня замечательный mySQL запрос — JOIN.
В этой публикации я расскажу о всех возможных вариантах работы с JOIN и более того, представлю принцип работы каждой команды — визуально.

Рассматривать мы будем:
  • INNER JOIN
  • LEFT JOIN
  • RIGHT JOIN
  • OUTER JOIN
  • LEFT JOIN EXCLUDING INNER JOIN
  • RIGHT JOIN EXCLUDING INNER JOIN
  • OUTER JOIN EXCLUDING INNER JOIN
  • Отдельно стоит отметить пункты 5,6 и 7. На самом деле эти запросы не соединяют две таблицы, а наоборот исключают из одной таблицы столбцы присутствующие в другой. На деле это может оказать очень полезным.

    Inner JOIN

    Один из самых распространенных запросов, встречается предельно часто. Этот запрос вернет все записи из левой таблицы (таб. А) и записи из (таб. В), но при этом возвращены будут только совпадающие столбцы.

    Пример запроса:

    Просмотр кода SQL

    SELECT < select_list> FROM Table_A A INNER JOIN Table_B B ON A. Key = B. Key

    Left JOIN

    Данный запрос вернет все столбцы из левой таблицы (таб. А), а также все столбцы из правой таблицы (таб. В) но только которые совпадают со столбцами из левой таблицы.

    Пример запроса:

    Просмотр кода SQL

    SELECT < select_list> FROM Table_A A LEFT JOIN Table_B B ON A. Key = B. Key

    Right JOIN

    Аналогичен предыдущему запросу, но уже вернет все столбцы из правой таблицы (таб. В), а также все столбцы из левой таблицы (таб. А) которые совпадают со столбцами из правой таблицы.

    Пример запроса:

    Просмотр кода SQL

    SELECT < select_list> FROM Table_A A RIGHT JOIN Table_B B ON A. Key = B. Key

    Outer JOIN

    Часто данный запрос записывают как FULL OUTER JOIN или FULL JOIN, все вариации выполняют одно действие, а именно возвращают все столбцы из обоих таблиц, при этом совпадающие столбцы будут перекрыты столбцами из левой таблицы.

    Пример запроса:

    Просмотр кода SQL

    SELECT < select_list> FROM Table_A A FULL OUTER JOIN Table_B B ON A. Key = B. Key

    Left Excluding JOIN

    Этот запрос вернет все столбцы из левой таблицы (таб. А), которые не совпадают со столбцами из правой таблицы (таб. В).

    Пример запроса:

    Просмотр кода SQL

    В MySQL выборку с помощью JOIN можно производить разными способами. Мы постараемся рассмотреть все эти виды запросов. Вот список всех запросов с участием JOIN:

  • INNER JOIN
  • LEFT JOIN
  • RIGHT JOIN
  • RIGHT JOIN без пересечений с левой таблицей
  • FULL OUTER
  • FULL OUTER где левая или правая таблица пустая
  • А вот иллюстрация к этим видам JOIN:

    Я прикреплю к статье файлы нашего сайта, среди которых будет join.php в которых я буду выводить все записи с помощью разных операторов JOIN.

    INNER JOIN

    Начнем мы с этого оператора INNER JOIN, потому что этот оператор срабатывает по умолчанию, если вы пишите в запросе просто JOIN. Этот оператор выбирает все записи из двух таблиц, где выполняется условие идущее после оператора ON. У нас есть две таблицы Files и Messages:

    Таблица Messages:

    Запрос с JOIN будет следующий:

    SELECT * FROM Messages INNER JOIN Files ON Messages.fid=Files.fid

    В результате будут выведены такие записи

    Таблица Files:

    LEFT JOIN будет нужен когда выводим все записи сообщений, а есть или нет прикрепленный файл, мы проверим уже через PHP.

    LEFT JOIN без пересечений с правой таблицей

    LEFT JOIN выводит все записи из левой таблицы, кроме тех в которых fid совпадают в правой таблице.

    Таблица Messages:

    Запрос с LEFT JOIN без пересечений будет следующий:

    SELECT * FROM Messages LEFT JOIN Files ON Messages.fid=Files.fid WHERE Files.fid IS NULL

    В результате мы получим вот такую вот выборку:

    Таблица Files:

    RIGHT JOIN будет нужен когда выводим все прикрепленные файлы без разницы используются они или нет, просто все файлы.

    RIGHT JOIN без пересечений

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

    Таблица Messages:

    Запрос с RIGHT JOIN без пересечений будет следующий:

    SELECT * FROM Messages RIGHT JOIN Files ON Messages.fid=Files.fid WHERE Messages.fid IS NULL

    Таким образом мы получим следующие данные:

    mid bodytext fid path
    NULL NULL 1 /files/1.png

    RIGHT JOIN будет нужен когда выводим все прикрепленные файлы, которые не прикреплены ни к каким сообщениям. Например, если мы хотим вывести файлы которые не используются.

    FULL OUTER JOIN

    Несмотря на то что в языке SQL есть FULL OUTER JOIN, в MySQL этого оператора нет . Дело в том что подобный оператор это огромная нагрузка на сервер. Сейчас у нас 3 файла и 3 сообщения, при этом образуется 4 строк в результате выполнения запроса. Я не уверен, что это хорошая идея писать запрос, который дает в совокупности два запроса LEFT JOIN и RIGHT JOIN. Но все же есть возможность эмулировать запрос FULL OUTER JOIN.

    Таблица Messages:

    Эмуляция запроса с FULL OUTER JOIN будет следующей:

    SELECT * FROM Messages LEFT JOIN Files ON Messages.fid = Files.fid UNION SELECT * FROM Messages RIGHT JOIN Files ON Messages.fid = Files.fid

    В этом запросе мы используем оператор UNION, чтобы объединить два запроса LEFT JOIN и RIGHT JOIN.

    В результате мы получим следующие записи:

    mid bodytext fid path
    1 Test 2 /files/2.png
    2 Hi NULL NULL
    3 Hello 3 /files/3.png
    NULL NULL 1 /files/1.png

    И здесь я уже затрудняюсь сказать зачем потребуется FULL OUTER JOIN. Но раз это есть в SQL, то видимо потребуется потом.

    FULL OUTER JOIN без пересечений

    Еще один вид JOIN еще более безумный, чем просто FULL OUTER JOIN, а именно FULL OUTER JOIN без пересечений. Я даже не могу предложить где можно использовать этот вид JOIN. Потому что в результате мы получаем файлы которые не используются и сообщения без файлов. И как вы наверно уже догадались этого оператора тоже нет в MySQL. Остается его только эмулировать с помощью двух операторов LEFT JOIN без перечений и RIGHT JOIN без пересечений.

    Эмуляция запроса FULL OUTER JOIN без пересечений:

    $sql = "SELECT * FROM Messages LEFT JOIN Files ON Messages.fid = Files.fid WHERE Files.fid IS NULL UNION SELECT * FROM Messages RIGHT JOIN Files ON Messages.fid = Files.fid WHERE Messages.fid IS NULL";

    В результате (исходные таблицы те же что и в примере с FULL OUTER JOIN) мы получим:

    mid bodytext fid path
    2 Hi NULL NULL
    NULL NULL 1 /files/1.png

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

    Кроме обычных простых запросов с простыми условиями язык SQL позволяет составлять довольно сложные выражения, на вил которых порой страшно смотреть, такими непонятными они выглядят. Однако такие запросы встречаются не очень часто, и следующий уровень сложности после обычного SELECT на мой взгляд идет команда JOIN. Давайте разберемся как с ней работать.

    Для начала давайте посмотрим простейшие часто употребимые запросы.

    SELECT COUNT(*) FROM table; //подсчет кол-ва записей SELECT * FROM table LIMIT 5,10; //начиная с 5-ой записи выберет 10 строк. чаще всего используется для постраничной навигации SELECT * FROM table ORDER BY num; //отсортирует все записи из таблицы по полю num SELECT * FROM table WHERE year="1990"; //выбрать запись/записи где значение year равно 1990 SELECT * FROM table WHERE name LIKE "%ova%"; //поиск в таблице имени в котором есть последовательность "ova" SELECT DISTINCT name FROM table; //если есть повторяющиеся поля то они будут учтены только один раз SELECT * FROM name WHERE age IN (12,15,18); // выведет имена которым соответствуют поля с возрастом 12,15,18 SELECT MAX(age) FROM table; //MAX/MIN - выберет запись с максимальным или минимальным значением age

    Теперь перейдем непосредственно к примерам JOIN:

    Очень популярная задача где используется команда JOIN это объединение нескольких таблиц имеющий какой то общий признак. Рассмотрим пример. Допустим у нас есть две таблицы. В первой хранятся данные об имени и адресе юзера и также есть колонка user_id. Во второй колонке у нас также есть колонка user_id и колонка с домашним индексом юзера.

    SELECT name, addres FROM table1 LEFT JOIN table2 ON table1.user_id=table2.user_id;

    Чтобы было еще понятнее, то этот запрос можно переписать классическим образом:

    SELECT table1.name, table1.addres, table2.index FROM table1, table2 WHERE table1.user_id = table2.user_id;

    Таким образом можно получить данные из нескольких таблиц, а если есть дополнительное условие то допишем и его:

    SELECT name, addres FROM table1 LEFT JOIN table2 ON table1.user_id=table2.user_id WHERE name = "Вася";

    Если окунуться в теорию, то добавим что есть следующие варианты JOIN:

    Тут будет уместно нарисовать знаменитые кружочки:

    INNER JOIN

    возвращает пересечение двух множеств

    SELECT t1.name, t2.city FROM Table1 t1 INNER JOIN Table2 t2 ON t1.key2 = t2.key2;

    Отражением INNER JOIN является OUTER JOIN. Нам предоставлено три типа OUTER JOIN – FULL, LEFT и RIGHT. Слово OUTER писать не обязательно.

    FULL JOIN

    Объединяет два множества

    FULL JOIN вернет ВСЕ записи из таблиц table и table2, без повторяющихся данных. Где данных нет, будет подставленно NULL.

    LEFT JOIN

    Возвращает данные из левой таблицы, а также данные из правой, которые пересекаются с левой.

    Если данных из правой таблицы будет не хватать, то подставится NULL значение.

    RIGHT JOIN – как вы наверное поняли, вернет все значения из правой таблицы и пересекающиеся данные из левой.

    Исключения

    Если нам понадобятся данные из первой таблицы для которых нет данных в правой, то нам просто надо добавить условие WHERE

    SELECT t1.name, t2.city FROM Table1 t1 LEFT JOIN Table2 t2 ON t1.key2 = t2.key2 WHERE t2.key2 IS NULL;

    Множественные JOIN

    С помощью JOIN можно соединить не только 2 таблицы, а сколько надо. Если вам надо соединить 2 таблицы, то потребуется 2 команды JOIN. Но не стоит впадать в крайность и объединять кучу таблиц, все это ощутимо скажется на производительности, поэтому иногда лучше выполнить несколько подзапросов. Пример соединения трех таблиц:

    SELECT t1.Name, t2.City, t3.Profession FROM Table1 t1 INNER JOIN Table2 t2 ON t1.key2 = t2.key2 INNER JOIN Table3 t3 ON t1.key3 = t3.key3;

    Что же, надеюсь перечисленные простые примеры JOIN помогли вам разобраться с этим оператором.

     
    Статьи по теме:
    Что такое расширение файла CDR?
    CDR-формат — это файл, который был создан в программе Corel DRAW, содержащей растровое или векторное изображение. Компания Corel использует этот формат в собственных продуктах, поэтому его можно открыть также другим программным обеспечением данной компани
    Multisim 17 где находится библиотека элементов
    Компоненты и библиотеки элементов Multisim 11 Контрольно-измерительные и индикаторные приборы В Multisim имеются измерительные приборы, каждый из которых можно использовать в схеме только один раз. Эти приборы рас­положены в библиотеке контрольно-из
    Универсальная последовательная шина USB В чем преимущества шины usb
    Универсальная последовательная шина Mini-B Connector ECN : извещение выпущено в октябре 2000 года. Errata, начиная с декабря 2000 : извещение выпущено в декабре 2000 года. Pull-up/Pull-down Resistors ECN Errata, начиная с мая 2002 : извещение выпущено в
    Календарь: как использовать онлайн-сервис для планирования личного времени
    Данное средство Outlook поможет вам спланировать наилучшим образом свои дела (встречи, собрания, события) в течение дня, недели или месяца. С помощью календаря Outlook можно планировать следующее. Встреча . Для этого требуется выделить время в деловом рас