Создавая этот запрос, мы присвоили «первому экземпляру» таблицы Customers псевдоним L, «второму экземпляру» – псевдоним R. В результате объединения «таблиц» мы получили всевозможные пары клиентов: первый клиент в каждой паре – это строка из «таблицы» L, второй – строка из «таблицы» R. С помощью условия WHERE L.rating = R.rating мы выбрали те пары, в которых рейтинг клиента из таблицы L (L.rating) равен рейтингу клиента из таблицы R (R.rating). Как и в предыдущем примере, к именам столбцов мы добавили в виде префикса имена «таблиц» (в данном случае – псевдонимы), чтобы указать, к какому из экземпляров таблицы относится каждый из столбцов.
Таким образом, запрос выводит следующие пары имен (табл. 2.12).
Поскольку наборы строк в «таблицах» L и R одинаковые, в результате запроса появилось много лишних данных: пары одинаковых имен (они возникли при сравнении строки «таблицы» L с точной копией этой строки в «таблице» R), а также одна и та же пара имен сначала в прямом, затем в обратном порядке. Чтобы избавиться от повторений, введите дополнительное условие отбора.
Таблица 2.12. Результат выполнения запросаПоскольку в действительности одинаковый рейтинг имеют только клиенты Крылов и ООО «Кускус», результатом этого запроса является единственная строка (табл. 2.13). Таблица 2.13. Результат выполнения запроса
Запросы, объединяющие таблицу с самой собой, можно использовать, в частности, для поиска ошибок дублирования данных в таблице, например для поиска клиентов с разными идентификаторами, но одинаковыми именами, адресами и телефонами.
Далее мы рассмотрим возможности комбинирования запросов.
Вложенные запросы
Результатом запроса является массив данных в виде таблицы, поэтому вы можете использовать результат одного запроса в другом запросе. Во многих случаях вложенными запросами можно заменить объединение таблиц. Например, получить список имен клиентов, когда-либо заказывавших товар № 5, можно с помощью вложенного запроса:Здесь вложенный запрос получают из таблицы Orders (Заказы) номера клиентов, заказавших товар № 5. Для обработки результатов подзапроса мы применили оператор IN, который возвращает истинное значение (TRUE), если элемент слева от оператора совпадает с одним из элементов списка справа от оператора. В данном случае оператор IN проверяет, содержится ли номер клиента (значение столбца id) в списке номеров, выданных подзапросом. Таким образом, внешний запрос выводит имена тех клиентов, номера которых получены в результате подзапроса (табл. 2.14). Таблица 2.14. Результат выполнения запроса
Однако не всегда вложенные запросы и объединения таблиц взаимозаменяемы. В частности, запросы с объединениями могут выводить данные из всех участвующих в запросе таблиц, а запросы с вложенными запросами, – только из таблиц, участвующих во внешнем запросе. А с помощью запросов, использующих групповые (агрегатные) функции в подзапросах, можно получить результат, не достижимый другими способами. Например, вывести заказ с наибольшей суммой можно только с помощью вложенного запроса, подсчитывающего максимальную сумму заказа: