MySQL subquery — как следует из названия, запросы, выполняемые внутри других запросов. Чаще всего subquery являются частью WHERE основного запроса, но это не всегда так.
Использование subquery может быть полезно при выполнении сложных запросов. В некоторых случаях такие выражения можно замещать выражениями с JOIN, но результат не всегда будет полностью верным.
MySQL subquery и как их использовать
SUBQUERY IN WHERE CLAUSE
Продолжим работу с тестовой базой данных и двумя таблицами.
Пример запроса с subquery в части запроса с условием WHERE
select city, price from PEOPLE WHERE city in (select city from REAL_ESTATE where price > 15000);
+——————+——-+
| city | price |
+——————+——-+
| Novosibirsk | 16000 |
| Sankt-Peterburg | 25000 |
+——————+——-+
Выборка производится изначально согласно внутреннему запросу, затем согласно внешнему уже учитывая результаты того, что уже выполнен.
Тот же результат можно получить используя JOIN
select PEOPLE.city, PEOPLE.price from PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.PRICE > 15000 and REAL_ESTATE.city = PEOPLE.city;
+——————+——-+
| city | price |
+——————+——-+
| Novosibirsk | 16000 |
| Sankt-Peterburg | 25000 |
| Novosibirsk | 16000 |
+——————+——-+
3 rows in set (0.00 sec)
Сейчас имеем два дубля, избавиться от них можно добавив distinct
select distinct PEOPLE.city, PEOPLE.price from PEOPLE, REAL_ESTATE WHERE REAL_ESTATE.PRICE > 15000 and REAL_ESTATE.city = PEOPLE.city;
+——————+——-+
| city | price |
+——————+——-+
| Novosibirsk | 16000 |
| Sankt-Peterburg | 25000 |
+——————+——-+
2 rows in set (0.00 sec)
В примере двумя способами получены идентичные результаты, на практике это не всегда так и при некоторых запросах с JOIN-ами определенные данные могут быть утеряны и результаты не будут полностью консистентными.
Использование subquery всегда является лучшей практикой, чем JOIN-ы
SUBQUERY IN FROM AND SELECT CLAUSES
Subqueries обычно используются при указании условия выполнения запроса where, также их можно применять для select и from
Например, такой запрос в котором SELECT выполняется внутри FROM. При этом используются алиасы и арифметические операции
select * from (select name,city,(price *12/1000) as thousands_for_year from PEOPLE) basic where name != 'Alexandr';
+———-+——————+———————+
| name | city | thousands_for_year |
+———-+——————+———————+
| Katerina | Yekaterinburg | 180 |
| Viktor | Moskow | 540 |
| Boris | Novosibirsk | 192 |
| Olga | Moskow | 600 |
| Nikolay | Sankt-Peterburg | 300 |
| Sergey | Krasnodar | 204 |
| Boris | Elabuga | 264 |
+———-+——————+———————+
7 rows in set (0.00 sec)
Запрос выводит информацию по таким колонкам как имя, город и потенциальный доход арендодателя в год со всех потенциальный съемщиков жилья, внесенных в таблицу PEOPLE за исключением тех, для которых в качестве имени задано Alexandr.