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