magazine (журнал); этот тип товара появляется в самом конце следующего
примера:
SELECT *
FROM product_types;
PRODUCT_TYPE_ID NAME
1 Book
2 Video
3 DVD
4 CD
5 Magazine
Можно увидеть этот тип товара с помощью правого внешнего соединения,
как показано в следующем примере; оператор внешнего соединения
на самом деле помещается слева от оператора равенства:
SELECT p.name, pt.name
FROM products p, product_types pt
WHERE p.product_type_id (+) == pt.product_type_id
ORDER BY p.name;
NAME NAME
2412: The Return Video
Chemistry Book
C la s s i c a l Music CD
C re a tive Y e l l CD
From Another Planet DVD
Modern Science Book
Pop 3 CD
58 Глава 2
Space Force 9
Supernova
Tank War
Z F i le s
DVD
Video
Video
Video
Magazine
Ограничения внешних соединений
На использование внешних соединений имеются ограничения, и в этом
разделе приведены некоторые из них.
Оператор внешнего соединения может быть помещен только с одной
из сторон соединения. Если вы попытаетесь поместить оператор внешнего
соединения с обеих сторон, то получите сообщение об ошибке:
П SQL> SELECT p.name, pt.name
2 FROM products p, product_types pt
3 WHERE p.product_type_id (+) = pt.product_types_id (+);
WHERE p.product_type_id (+) = pt.product_types_id (+)
ERROR at l in e 3:
0RA-01468: a predica te may reference only one o u te r - jo in e d ta b le
(0RA-01468: предикат может ссылаться только на одну соединенную внешним
образом таблицу)
Нельзя использовать условие внешнего соединения с оператором IN:
□ SQL> SELECT p.name, pt.name
2 FROM products p, product_types pt
3 WHERE p.product_type_id (+) IN (1, 2, 3, 4);
WHERE p.product_type_id (+) IN (1, 2, 3, 4)
ERROR at l in e 3:
0RA-01719: outer jo in operator (+) not allowed in operand of OR or IN
(0RA-01719:оператор внешнего соединения (+) не разрешен в операндах OR
или IN)
Нельзя использовать условие внешнего соединения с другим соединением,
использующим оператор OR:
□ SQL> SELECT p.name, pt.name
2 FROM products p, product_types pt
3 WHERE p.product_type_id (+) = pt.product_type_id
4 OR p.product_type_id = 1;
WHERE p.product_type_id (+) = pt.product_type_id
ERROR at l in e 3:
0RA-01719: outer jo in operator (+) not allowed in operand of OR or IN
(0RA-01719:оператор внешнего соединения (+) не разрешен в операндах OR
или IN)
Примечание Эти ограничения встречаются наиболее часто при использовании оператора
внешнего соединения. Полный перечень подобных ограничений вы сможете найти в справочнике
по Oracle SQL (SQL Reference) корпорации Oracle.
Выборка информации из таблиц базы данных 59
Самосоединения
Самосоединение (self jo in ) получается в результате соединения таблицы с
самой собой. Для выполнения самосоединения нужно присвоить таблице
разные псевдонимы, чтобы иметь возможность идентифицировать каждое
обращение к таблице. Таблица employees содержит столбец manage r _ id ,
который хранит employee_id менеджера каждого из сотрудников; если у сотрудника
нет менеджера, то employee_id содержит n u ll . В таблице employees
содержатся следующие строки:
.ID MANAGER_ID FIRST_NAME LAST_NAME TITLE SALARY
1 James Smith CEO 800000
2 1 Ron Johnson Sales Manager 600000
3 2 Fred Hobbs Salesperson 150000
4 2 Susan Jones Salesperson 500000
У Джеймса Смита - CEO - в столбце manage r_id содержится пустое значение,
то есть у него нет начальника. Фред Хоббс и Сьюзен Джонс подчиняются
Рону Джонсону, а Рон Джонсон подчиняется Джеймсу Смиту.
Самосоединение можно использовать, например, чтобы показать
имена каждого сотрудника и его менеджера. В следующем примере таблица
employees упоминается дважды с использованием двух псевдонимов:
w (сотрудник) и m (менеджер). Псевдоним w используется для получения
имени служащего, а псевдоним m - для получения имени его менеджера.
Самосоединение осуществляется между столбцами w.manager id и т.
employee_id:
□ SELECT w.first_name || ' ' || w.last_name || 'works for ' ||
m.first_name || ‘ ' || m.last_name
FROM employees w, employees m
WHERE w.manager_id = m.employee_id
ORDER BY w.first_name;
W. FIRST_NAME| | ” | |W. LAST_NAME| ) ’ WORKSFOR’ | |M.FIRST_NA
Fred Hobbs works fo r Ron Johnson
Ron Johnson works fo r James Smith
Susan Jones works fo r Ron Johnson
Так как у Джеймса Смита в столбце manager_id содержится n u l l (пусто),
строка для него не выводится.
Вы можете выполнять внешние соединения в сочетании с самосоеди-
нениями. В следующем примере внешнее соединение используется в сочетании
с самосоединением из предыдущего примера, чтобы получить строку
для Джеймса Смита. Обратите внимание на использование функции
NVL( ) для вставки строки, указывающей, что Джеймс Смит работает на акционеров
магазина (он CEO и должен отчитываться перед акционерами
компании):
П SELECT w.last_name || 'works fo r ' ||
NVL(m.last_name, ‘ the sh a reh o ld e rs ’ )
60 Глава 2
FROM employees w, employees m