Выбрать главу

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