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

WHERE w.manager_id = m.employee_id

ORDER BY w.last_name;

W.LAST_NAME||’WORKSFOR’ ||NVL(M.LAST_N

Smith works fo r the shareholders

Johnson works fo r Smith

Hobbs works fo r Johnson

Jones works fo r Johnson

Выполнение соединений с использованием

синтаксиса SQL/92

До сих пор для выполнения соединений использовался синтаксис соединений

Oracle, основанный на стандарте ANSI SQL/86. Начиная с Oracle9i,

в базе данных реализован и стандарт соединений ANSI SQL/92 и вам следует

использовать его в своих запросах. В этом разделе вы увидите, как

использовать SQL/92 и как он помогает избежать появления нежелательных

декартовых произведений.

Примечание Web-сайт ANSI расположен по адресу www.ansi.org.

Выполнение внутренних соединений для двух таблиц

с использованием SQL/92

Раньше для выполнения внутреннего соединения с использованием стандарта

SQL/86 использовался следующий запрос:

□ SELECT p.name, pt.name

FROM products p, productjtypes pt

WHERE p.product_type_id = pt.produc t_types_id

ORDER BY p.name;

Стандарт SQL/92 вводит для выполнения внутренних соединений фразы

INNER JOIN и ON. В данном ниже примере предыдущий запрос переписывается

с использованием фраз INNER JOIN и ON:

□ SELECT p.name, pt.name

FROM products p INNER JOIN product_types pt

ON p.product_type_id = pt.produc t_type s_id

ORDER BY p.name;

Во фразе ON можно использовать операторы неэквивалентности. Ранее

был показан запрос, использующий стандарт SQL/86 для выполнения соединений

по неэквивалентности:

□ SELECT е . first_name, e.last_name, е . t i t l e , е . sa la ry ,

sg.salary_grade_id

FROM employees e, salary_grades sg

WHERE e . s a la r y BETWEEN sg .low_ sa la ry AND sg .h ig h _ sa la ry

ORDER BY salary_grade_id;

Выборка информации из таблиц базы данных 61

Ниже приводится этот же запрос, записанный с использованием стандарта

SQL/92:

□ SELECT е . first_name, e.last_name, е . t i t l e , е . sa la ry ,

sg.salary_grade_id

FROM employees e INNER JOIN salary_grades sg

ON e . s a la r y BETWEEN sg.low_ sa la ry AND sg .h ig h _ sa la ry

ORDER BY salary_grade_id;

Упрощение соединений с помощью ключевого слова USING

Стандарт SQL/92 позволяет еще больше упростить условие соединения

посредством фразы USING, но со следующими ограничениями:

■ в запросе должно использоваться соединение по эквивалентности,

■ столбцы, по которым выполняется соединение, должны иметь одинаковые

имена.

Большинство выполняемых соединений являются соединениями по эквивалентности,

и если всегда использовать те же самые имена как для первичного

ключа одной таблицы, так и для внешних ключей других таблиц,

то можно удовлетворить приведенные выше ограничения.

Следующий запрос использует фразу USING вместо фразы ON:

П SELECT p.name, pt.name

FROM products p INNER JOIN product_types pt

USING (produc t_ type_ id) ;

Чтобы увидеть столбец product_type_id, достаточно просто указать имя

этого столбца, не указывая во фразе SELECT ни имени таблицы, ни ее псевдонима:

□ SELECT p.name, pt.name, product_type_id

FROM products p INNER JOIN product_types pt

USING (produc t_ type_ id) ;

При попытке указать вместе с именем столбца псевдоним таблицы, например,

p. product_type_id, будет получено сообщение об ошибке:

□ SQL> SELECT p.name, pt.name, p.product_type_id

2 FROM products p INNER JOIN product_types pt

3 USING (product_type_id);

SELECT p.name, pt.name, p.product_type_id

ERROR at l in e 1:

ORA-25154: column part of USING clause cannot have q u a l i f ie r

(ORA-25154: в столбцовой части фразы USING не может быть квалификаторов)

Кроме того, во фразе USING вы можете использовать только само имя

столбца. Если бы в предыдущем примере вы попытались указать USING(p.

product_type_id) вместо USING(product_type_id), было бы получено следующее

сообщение об ошибке:

П SQL> SELECT p.name, pt.name, p.product_type_id

2 FROM products p INNER JOIN product_types pt

62 Глава 2

3 USING (product_type_id);

USING (p.product_type_id)

ERROR at l in e 3:

0RA-01748: only simple column names allowed here

(0RA-01748: здесь разрешены только простые имена столбцов)

Предупреждение При ссылке на столбцы во фразе USING не следует использовать имя

таблицы и ее псевдоним. В противном случае вы получите сообщение об ошибке.

Выполнение внутренних соединений более чем для двух таблиц

с использованием SQL/92

Ранее был приведен запрос по стандарту SQL/86, выполняющий выборку

строк из таблиц customers, purchases, products и product_types:

□ SELECT с . first_name, c.last_name, p.name AS PRODUCT, pt.name AS TYPE

FROM customers c, purchases pr, products p, product_types pt

WHERE c.customer_id = pr.customer_id

AND p.product_id = pr .produc t_id

AND p.product_type_id - p f . product_type_id

ORDER BY p.name;

Следующий пример переписывает этот запрос, используя SQL/92; обратите

внимание, как осуществляется навигация по отношениям внешних

ключей при использовании фраз INNER JOIN и USING:

□ SELECT с . first_name, c.last_name, p.name AS PRODUCT, pt.name AS TYPE

FROM customers с INNER JOIN purchases pr

USING(customer_id)

INNER JOIN products p