Операция, которая бывает часто полезна, это объединение двух запросов, в котором второй запрос выбирает строки, исключённые первым. Наиболее часто вы будете делать это, чтобы не исключать строки, которые не удовлетворили предикату при объединении таблиц. Это называется внешним объединением.
Предположим, что некоторые из ваших заказчиков ещё не были назначены продавцам. Вы можете захотеть увидеть имена и города всех ваших заказчиков, с именами продавцов, не учитывая тех, кто ещё не был назначен. Вы можете достичь этого, формируя объединение из двух запросов, один из которых выполняет объединение, а другой выбирает заказчиков с пустыми (NULL) значениями поля snum. Этот последний запрос должен вставлять пробелы в поля, соответствующие полю sname в первом запросе. Как и раньше, вы можете вставлять текстовые строки в ваш вывод чтобы идентифицировать запрос, который вывел данную строку.
Использование этой методики во внешнем объединении дает возможность использовать предикаты для классификации, а не для исключения. Мы и раньше использовали пример нахождения продавцов с заказчиками, размещёнными в их городах. Однако, вместо просто выбора только этих строк, вы, возможно, захотите, чтобы ваш вывод перечислял всех продавцов и указывал тех, кто не имел заказчиков в их городах, и кто имел. Следующий запрос, чей вывод показан на Рисунке 14.6, выполнит это:
SELECT Salespeople.snum, sname, cname, comm FROM Salespeople, Customers WHERE Salespeople.city = Customers.city.
UNION
SELECT snum, sname, ' NO MATCH ', comm FROM Salespeople WHERE NOT city = ANY (SELECT city FROM Customers)
ORDER BY 2 DESC;
=============== SQL Execution Log ============ | | | FROM Salespeople | | WHERE NOT city = ANYate) | | (SELECT city | | FROM Customers) | | ORDER BY 2 DESC; | | ============================================= | | | | ----- ------- --------- ------------ | | 1002 Serres Cisneros 0.1300 | | 1002 Serres Liu 0.1300 | | 1007 Rifkin NO MATCH 0.1500 | | 1001 Peel Clemens 0.1200 | | 1001 Peel Hoffman 0.1200 | | 1004 Motika Clemens 0.1100 | | 1004 Motika Hoffman 0.1100 | | 1003 Axelrod NO MATCH 0.1000 | | | ===============================================