MySQL SELECT JOIN — запрос на временное объединение двух таблиц. При использовании MySQL SELECT JOIN применяется для объединения значений нескольких таблиц и поиска по ним одним запросом.
Цикл по принципам работы с MySQL, более ранние материалы:
- Вводная статья цикла
- Начало работы с MySQL и основные команды
- MySQL SELECT, выборка из таблиц MySQL
- Регулярные выражения в 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.