MySQL SELECT: JOIN таблиц


MySQL SELECT JOIN — запрос на временное объединение двух таблиц. При использовании MySQL SELECT JOIN применяется для объединения значений нескольких таблиц и поиска по ним одним запросом.



Цикл по принципам работы с MySQL, более ранние материалы:
  1. Вводная статья цикла
  2. Начало работы с MySQL и основные команды
  3. MySQL SELECT, выборка из таблиц MySQL
  4. Регулярные выражения в MySQL


MySQL SELECT JOIN и выборка из двух и более таблиц


SQL — декларативный язык, основанный на реляционной алгебре — он имеет в качестве компонента оптимизатор запросов, преобразующий пользовательский ввод и находящий самый простой и быстрый способ выполнить запрос. Поскольку в основе реляционная алгебра все ее законы применимы к SQL и его имплементациям вроде MySQL. Среди них объединение элементов для того чтобы выполнить запрос на выборку или обновление данных по обоим их них. Это MySQL SELECT JOIN и его подвиды.



Выборка по нескольким условиям


Продолжим работу с двумя существующими таблицами и продемонстрируем как работают JOIN



Выберем несколько значений из таблицы PEOPLE, условием является готовность человека, данные которого присутствуют в таблице платить за жилье более 15000 рублей в месяц.

SELECT name, age, city, PRICE FROM PEOPLE WHERE PRICE > 15000;

+———-+——+——————+——-+
| name | age | city | PRICE |
+———-+——+——————+——-+
| Alexandr | 28 | Moskow | 50000 |
| Viktor | 29 | Moskow | 45000 |
| Boris | 27 | Novosibirsk | 16000 |
| Olga | 18 | Moskow | 50000 |
| Nikolay | 24 | Sankt-Peterburg | 25000 |
| Sergey | 22 | Krasnodar | 17000 |
+———-+——+——————+——-+
6 rows in set (0.00 sec)



Можно осуществлять выборку по условию и не выводя в качестве результата само условие — значение поля PRICE в данном случае


SELECT name, age, city FROM PEOPLE WHERE PRICE > 15000;

+———-+——+——————+
| name | age | city |
+———-+——+——————+
| Alexandr | 28 | Moskow |
| Viktor | 29 | Moskow |
| Boris | 27 | Novosibirsk |
| Olga | 18 | Moskow |
| Nikolay | 24 | Sankt-Peterburg |
| Sergey | 22 | Krasnodar |
+———-+——+——————+
6 rows in set (0.00 sec)



Теперь перейдем к простейшему MySQL SELECT JOIN-у и выберем имена людей, соответствующие записям для которых значения rentorsale в таблицах REAL_ESTATE и PEOPLE различаются.



SELECT name FROM PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.rentorsale != PEOPLE.rentorsale;

+———-+
| name |
+———-+
| Alexandr |
| Katerina |
| Viktor |
| Boris |
| Olga |
| Nikolay |
| Sergey |
+———-+
7 rows in set (0.00 sec)



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



От дублирования результатов SELECT запросов можно избавиться добавляя ключевое слово DISTINCT

SELECT name FROM PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.rentorsale = PEOPLE.rentorsale;



В выводе длинный список имен, всего 84 результата. Большая часть из них — дубли.

Убедимся в этом добавив DISTINCT



SELECT distinct name FROM PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.rentorsale = PEOPLE.rentorsale;

+———-+
| name |
+———-+
| Alexandr |
| Katerina |
| Viktor |
| Boris |
| Olga |
| Nikolay |
| Sergey |
+———-+
7 rows in set (0.00 sec)



С JOIN-ами могут соседствовать и другие условия — например, ограничения на записи из таблицы PEOPLE в виде условия PRICE > 20000


SELECT distinct name FROM PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.rentorsale = PEOPLE.rentorsale and PEOPLE.PRICE > 20000;

+———-+
| name |
+———-+
| Alexandr |
| Viktor |
| Olga |
| Nikolay |
+———-+
4 rows in set (0.00 sec)



Однако, возможно возникновение ошибок. Если вместо имен выводить районы города (в которых находятся квартиры и в которых квартиры желают снять или купить) — значения поля district возникнет неоднозначность


SELECT district FROM PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.rentorsale = PEOPLE.rentorsale and PEOPLE.PRICE > 20000;

ERROR 1052 (23000): Column 'district' in field list is ambiguous



Причина в том, что поле district есть в обеих таблицах и MySQL не знает какие значения выводить.



Исправить ситуацию можно только непосредственно задав имя таблицы

SELECT PEOPLE.district FROM PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.rentorsale = PEOPLE.rentorsale and PEOPLE.PRICE > 20000;


Такой запрос вернет 28 результатов



SELECT запросы можно усложнять и добавлять новые условия, JOIN-ов в условии WHERE может быть больше одного

SELECT PEOPLE.district FROM PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.rentorsale = PEOPLE.rentorsale and PEOPLE.PRICE > 20000 and REAL_ESTATE.district = PEOPLE.district;

+————+
| district |
+————+
| Center |
| Center |
| Center |
| Center |
| Center |
| Center |
| Primorskiy |
| Center |
| Center |
| Center |
+————+
10 rows in set (0.00 sec)



Читайте про MySQL subquery или подзапросы MYSQL.

Сказать спасибо