Одна из наиболее важных черт запросов SQL состоит в их способности определять связи между множеством таблиц и отображать содержащуюся в них информацию в терминах этих связей в рамках единственной команды. Операция такого рода называется соединением (соединение таблиц). Фактически, наличие операции соединения является едва ли не самым главным, что отличает реляционные системы от систем других типов.
При операции соединения таблицы перечисляются в предложении запроса FROM; имена таблиц разделяются запятыми. Предикат запроса может ссылаться на любой столбец любой из соединяемых таблиц и, следовательно, может использоваться для установления связей между ними. Обычно предикат сравнивает значения в столбцах различных таблиц для того, чтобы определить, удовлетворяется ли условие WHERE.
При операции соединения таблицы перечисляются в предложении запроса FROM; имена таблиц разделяются запятыми. Предикат запроса может ссылаться на любой столбец любой из соединяемых таблиц и, следовательно, может использоваться для установления связей между ними. Обычно предикат сравнивает значения в столбцах различных таблиц для того, чтобы определить, удовлетворяется ли условие WHERE.
1. Предположим, нужно установить связь между продавцами (Salespeople) и покупателями (Customers) в соответствии с местом их проживания, чтобы получить все возможные комбинации продавцов и покупателей из одного города. Для этого необходимо взять продавца из таблицы Salespeople и выполнить по таблице Customers поиск всех покупателей, имеющих то же значение в столбце city:
SELECT Customers.cname, Salespeople.sname, Salespeople.city FROM Salespeople, Customers WHERE Salespeople.city = Customers.city;
Во избежание двусмысленности в выборке ссылки на поля во фразе WHERE должны уточняться именами содержащих их таблиц.
Операция соединения таблиц посредством ссылочной целостности применяется для использования связей, встроенных в базу данных.
2. Например, чтобы показать соответствие имен покупателей именам продавцов, обслуживающих этих покупателей, используется следующий запрос:
2. Например, чтобы показать соответствие имен покупателей именам продавцов, обслуживающих этих покупателей, используется следующий запрос:
SELECT Customers.cname, Salespeople.sname FROM Customers, Salespeople WHERE Salespeople.snum = Customers.snum;
Соединение, использующее предикаты, основанные на равенствах, называется эквисоединением. Рассмотренные выше примеры относятся именно к этой категории, поскольку все условия в предложении WHERE базируются на математических выражениях, использующих символ равенства. Эквисоединение является наиболее распространенным типом соединения., но существуют и другие. Фактически в соединении можно использовать любой оператор сравнения.
3. Например, следующее соединение генерирует все комбинации имен продавцов и покупателей так, что первые предшествуют последним в алфавитном порядке, а последние имеют рейтинг меньше 200:
SELECT sname, cname FROM Salespeople, Customers WHERE sname < cname AND rating < 200;
4. Можно конструировать запросы путем соединения более чем двух таблиц. Например, нам нужно найти все заявки покупателей, не находящихся в том же городе, что и их продавец. Для потребуется связать все три рассматриваемые таблицы:
SELECT onum, cname, Orders.cnum, Orders.snum FROM Salespeople, Customers, Orders WHERE Customers.city <> Salespeople.city AND Orders.cnum = Customers.cnum AND Orders.snum = Salespeople.snum;
Хотя команда выглядит достаточно сложно, следуя ее логике, легко убедиться, что в выходных данных будут перечислены покупатели и продавцы, расположенные в разных городах (они сравниваются по полю snum), и что указанные заказы сделаны именно этими покупателями (подбор заказов устанавливается в соответствие с полями cnum и snum таблицы Orders).
В некоторых, довольно часто встречающихся на практике случаях, необходимо выбрать данные из таблицы, основываясь на результатах дополнительных выборок из этой же таблицы. Такие выборки называются коррелированными. Для их выполнения используются псевдонимы таблиц (алиасные имена), которые следуют непосредственно за именем таблицы в выборке. В приведенном ниже примере используются псевдонимы таблицы CUSTOMERS: first и second.
5. Выбрать все пары продавцов, имеющих одинаковый рейтинг, можно следующей командой:
SELECT first.cname, second.cname, first.rating FROM Customers first, Customers second WHERE first.rating = second.rating AND first.cname < second.cname;
В приведенном примере команда SQL ведет себя так, как будто в операции соединения участвуют две таблицы, называемые «first» и «second». Обе они в действительности являются таблицей Customers, но алиасы позволяют рассматривать ее как две независимые таблицы. Алиасы first и second были определены в предложении запроса FROM непосредственно за именем таблицы. Алиасы применяются также в предложении SELECT, несмотря на то, что они не определены вплоть до предложения FROM. Это совершенно оправдано. SQL сначала примет какой-либо из таких алиасов на веру, но затем отвергнет команду, если в предложении FROM запроса алиасы не определены. Время жизни алиаса зависит от времени выполнения команды. После выполнения запроса используемые в нем алиасы теряют свои значения. Получив две копии таблицы Customers для работы, SQL выполняет операцию JOIN, как для двух разных таблиц: выбирает очередную строку из одного алиаса и соединяет ее с каждой строкой другого алиаса. Для исключения повторений необходимо задать порядок для двух значений так, чтобы одно значение было меньше, чем другое, или предшествовало в алфавитном порядке.
Чтобы соединение возвращало данные одной таблицы даже при отсутствии соответствующей записи в другой таблице, можно создать внешнее соединение с помощью строки символов (+) в сравнении, формирующем соединение таблиц.
6. В данном примере выбираются строки, содержащие имена и должности сотрудников с указанием названий отделов, в которых они работают. При этом в результирующую выборку попадает также отдел OPERATIONS, в котором не работает ни одного служащего
6. В данном примере выбираются строки, содержащие имена и должности сотрудников с указанием названий отделов, в которых они работают. При этом в результирующую выборку попадает также отдел OPERATIONS, в котором не работает ни одного служащего
SELECT ename, job, dept.deptno, dname FROM emp, dept WHERE emp.deptno (+) = dept.deptno;
Результат выполнения данного запроса:
SQL Соединение таблиц.