Комбинированные запросы
14. Комбинированные запросы
В большинстве SQL-запросов используется один оператор, посредством которого возвращаются данные из одной или нескольких таблиц. SQL позволяет также выполнять множественные запросы, за счет многократного использования оператора SELECT, и возвращать результаты в виде одного набора результатов запроса. Такие комбинированные запросы обычно называют соединениями или сложными запросами.
Можно назвать два основных сценария, для выполнения которых понадобятся сложные запросы:
· для возвращения одинаковым образом структурированных данных из различных таблиц посредством одного запроса;
· для выполнения многократных запросов к одной таблице и возвращения данных в виде результата одного запроса.
Результат комбинирования двух запросов к одной и той же таблице в основном аналогичен результату, полученному при выполнении одного запроса с несколькими требованиями в предложении WHERE.
14.1. Создание комбинированных запросов
Запросы в языке SQL комбинируются с помощью оператора UNION. Этот оператор позволяет многократно указывать оператор SELECT, и по завершении их работы может быть выведен один набор результатов.
Использовать оператор UNION просто – надо указать каждый необходимый оператор SELECT и разместить ключевое слово UNION между ними.
Рекомендуемые материалы
Пример. Необходимо получить отчет, содержащий сведения обо всех клиентах из штата Иллинойс, Индиана и Мичиган. Также включить в него данные о клиенте Fun4All независимо от штата.
Можно создать условие WHERE, благодаря которому будет выполнено требуемое, но удобнее использовать оператор UNION. Применение оператора UNION подразумевает многократное использование операторов SELECT.
Рассмотрим отдельно операторы.
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN (‘IL’,’IN’,’MI’);
--------------------------
cust_name cust_contact cust_email
Village Toys John Smith sales@villagetoys.com
Fun4All Jim Jones jjones@fun4all.com
The Toy Store Kim Howard
Этот оператор SELECT выбирает все строки, относящиеся к штатам Иллинойс, Индиана и Мичиган.
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = ‘Fun4All’;
--------------------------
cust_name cust_contact cust_email
Fun4All Jim Jones jjones@fun4all.com
Fun4All Denise L. Stephens dstephens@fun4all.com
Этот оператор использует простую проверку на равенство, чтобы найти все местонахождения в таблицах клиента Fun4All.
Скомбинируем эти два запроса в один.
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN (‘IL’,’IN’,’MI’);
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = ‘Fun4All’;
--------------------------
cust_name cust_contact cust_email
Fun4All Denise L. Stephens dstephens@fun4all.com
Fun4All Jim Jones jjones@fun4all.com
The Toy Store Kim Howard
Village Toys John Smith sales@villagetoy.com
Оператор UNION указывает СУБД выполнить оба оператора SELECT и вывести результаты в виде набора результатов запроса.
Для сравнения приведем тот же самый запрос, использующий не оператор UNION, а несколько предложений WHERE.
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN (‘IL’,’IN’,’MI’);
OR cust_name = ‘Fun4All’;
--------------------------
cust_name cust_contact cust_email
Village Toys John Smith sales@villagetoy.com
Fun4All Denise L. Stephens dstephens@fun4all.com
Fun4All Jim Jones jjones@fun4all.com
The Toy Store Kim Howard
В этом простом примере применение оператора UNION оказывается более сложным. Однако если условие фильтрации окажется более сложным или если понадобится выбрать данные из многих таблиц, то оператор UNION может значительно упростить процесс.
В стандартном SQL не существует ограничений на число операторов SELECT, которые могут быть скомбинированы посредством операторов UNION.
В большинстве СУБД используется внутренний оптимизатор запросов, комбинирующий операторы SELECT, прежде чем СУБД начинает их обработку.
14.2. Правила применения запросов UNION
Существуют следующие правила:
· запрос UNION должен включать два или более операторов SELECT, отделенных один от другого ключевым словом UNION;
· каждый запрос в операторе UNION должен содержать одни и те же столбцы, выражения или статистические функции, кроме того, столбцы должны быть перечислены в одном и том же порядке;
· типы данных столбцов должны быть совместимыми. Они не обязательно должны быть одного типа, но они должны быть того типа, который СУБД сможет однозначно преобразовать.
14.3. Включение или исключение повторяющихся строк
Если проанализировать запросы с UNION, то можно заметить, что, когда они выполняются отдельно, первый оператор SELECT возвращает три строки, второй – две. Однако когда эти два оператора SELECT комбинируются с UNION, возвращается только четыре строки, а не пять.
Запрос UBION автоматически удаляет все повторяющиеся строки из набора результатов запроса, т.е. он ведет себя точно так же, как вели бы себя несколько предложений WHERE в одном операторе SELECT. Поскольку присутствует запрсь о клиенте Fun4All из штата Индиана – эта строка была возвращена обоими операторами SELECT. Когда же использовался запрос UNION, повторяющаяся строка была удалена.
Таково поведение запроса UNION по умолчанию, но при желании можно изменить его. Если требуется возвратить все вхождения, необходимо использовать UNION ALL вместо UNION.
Рассмотрим следующий пример.
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN (‘IL’,’IN’,’MI’);
UNION ALL
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = ‘Fun4All’;
--------------------------
cust_name cust_contact cust_email
Village Toys John Smith sales@villagetoy.com
Fun4All Jim Jones jjones@fun4all.com
The Toy Store Kim Howard
Fun4All Jim Jones jjones@fun4all.com
Fun4All Denise L. Stephens dstephens@fun4all.com
При использовании запроса UNION ALL СУБД не удаляет дубликаты. Поэтому возвращено пять строк, одна из них повторяется дважды.
14.4. Сортировка результатов комбинированных запросов
Результат применения оператора SELECT сортируется с помощью предложения ORDER BY. При комбинировании запросов посредством UNION только одно предложение ORDER может быть использовано, и оно должно появиться после заключительного оператора SELECT.
В следующем примере сортируются результаты, полученные предыдущим запросом UNION.
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN (‘IL’,’IN’,’MI’);
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = ‘Fun4All’
ORDER BY cust_name, cust_contact;
--------------------------
cust_name cust_contact cust_email
Fun4All Denise L. Stephens dstephens@fun4all.com
Fun4All Jim Jones jjones@fun4all.com
Рекомендуем посмотреть лекцию "Полулунные клапаны".
The Toy Store Kim Howard
Village Toys John Smith sales@villagetoy.com
Несмотря на то что ORDER BY является частью только последнего оператора SELECT, на самом деле СУБД будет использовать его для сортировки всех результатов, возвращенных всеми операторами SELECT.
14.4. Другие типы запроса на соединение
Некоторые СУБД поддерживают два дополнительных запроса типа UNION. Оператор EXCEPT (иногда называемый MINUS) может быть использован только для чтения строк, которые существуют в первой таблице, но не во второй. Оператор INTERSECT можно использовать для чтения строк, которые имеются в обеих таблицах. Однако на практике такие запросы UNION используются редко, поскольку те же самые результаты могут быть получены посредством объединений.