PRODUCTS_TBL
PROD_ID VARCHAR2UO) NOT NULL Ключевое поле
PROD_DESC VARCHAR2(40) NOT NULL
COST NUMBER (6,2) NOT NULL
Необходимо использовать таблицы CUSTOMERJTBL и pfi ODUCTS_TBL. У этих таблиц нет общих столбцов, по которым можно было бы выполнить связывание. Приходится использовать таблицу ORDERS_TBL, в которой имеется поле CUST_ID, присутствующее и в таблице CUSTOMER_TBL, и в таблице PRODUCTS_TBL. Условия связывания и результаты выглядят следующим образом.
SELECT C.CUST_NAME, P.PROD_DESC FROM CUSTOMER_TBL С,
PRODUCTS_TBL P,
ORDERS_TBL О
WHERE C.CUST_ID = O.CUST_ID AND P.PROD_ID = O.PROD_ID;
CUST_NAME PROD_DESC
LESLIE GLEASON КОСТЮМ ВЕДЬМЫ
SCHYLERS NOVELTIES ПЛАСТИКОВЫЕ ТЫКВЫ
WENDY WOLF ПЛАСТИКОВЫЕ ТЫКВЫ
GAVINS PLACE ФОНАРИ
SCOTTYS MARKET ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ
ANDYS CANDIES ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ
6 строк выбраны.
Обратите внимание на назначение таблицам псевдонимов и их использование в выражении ключевого слова WHERE.
Декартово произведение
Декартово произведение является результатом декартова связывания (CARTESIAN JOIN) или отсутствия связывания таблиц в запросе. Если в запросе указываются две или более таблиц и не используется их связывание, то в выводе будут присутствовать все возможные комбинации строк выбранных таблиц. Если таблицы большие, в результате получится, может быть, сотни, тысячи или даже миллионы записей. При использовании в запросе декартова произведения таблиц настоятельно рекомендуется использовать ключевое слово WHERE. Декартово произведение таблиц иначе называется кросс-связыванием (cross join).
Синтаксис соответствующей части оператора следующий.
FROM таблица1, таблица2 [,таблицаЗ ]
WHERE таблица1, таблица2 [,таблицаЗ ]
Вот пример кросс-связывания или ужасного декартова произведения таблиц.
SELECT E.EMP_ID, E.LAST_NAME, P.POSITION
FROM EMPLOYEE_TBL E,
EMPLOYEE_PAY_TBL P;
EMP ID
LAST NAM
POSITION
311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555
STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS
MARKETING MARKETING MARKETING MARKETING MARKETING MARKETING TEAM LEADER TEAM LEADER TEAM LEADER TEAM LEADER TEAM LEADER TEAM LEADER SALES MANAGER SALES MANAGER SALES MANAGER SALES MANAGER SALES MANAGER SALES MANAGER SALESMAN SALESMAN SALESMAN SALESMAN SALESMAN SALESMAN SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER
313782439 220984332 443679012
GLASS WALLACE SPORGEON
SHIPPER SHIPPER SHIPPER
36 строк выбраны.
Ввиду того, что никакого связывания не было задано, данные были выбраны из двух отдельных таблиц. Не было указано, как связывать записи одной таблицы с записями другой, и поэтому сервер базы данных связал каждую запись одной таблицы со всеми записями другой. В каждой из этих таблиц было по 6 записей, поэтому в результате их получилось 36.
Чтобы разобраться в том, что такое декартово произведение таблиц, рассмотрите следующие примеры.
SQL> SELECT X FROM TABLE1;
X
-
A
В
С
D
4 строки выбраны
SQL> SELECT X FROM TABLE2;
X
-
A
В
С
D
4 строки выбраны.
SQL> SELECT TABLE1.X, TABLE2.X
2* FROM TABLE1, TABLE2;
X X
_ _
A A
В А
С А
D A
А В
в в
с в
D В
А С
в с
с с
D С
A D
В D
С D
D D
16 строк выбраны.
При связывании таблиц в запросе всегда следует быть внимательным. Если какие-то две таблицы в запросе окажутся не связанными и число записей в каждой из них будет около 1000, то их прямое произведение будет содержать уже 1000000 выводимых записей.
Резюме
Вы получили представление об одной из важнейших возможностей SQL - связывании таблиц. Представьте, какие были бы ограничения, если бы в запросе нельзя было извлечь данные из нескольких таблиц сразу. Мы с вами рассмотрели несколько типов связывания таблиц, каждый из которых выполняет свои задачи в зависимости от условий запроса. Данные можно связывать по равенству или по неравенству. Внешнее связывание позволяет извлекать данные из связанных таблиц даже тогда, когда не все записи одной таблицы имеют соответствующие записи в другой. Рекурсивное связывание позволяет связать таблицу саму с собой. Берегитесь кросс-связывания, известного так же, как декартово произведение таблиц. В результате декартова произведения, возникающего при использовании в запросе нескольких таблиц без их связывания, объем выводимых данных может оказаться огромным. При выборе данных из нескольких таблиц внимательно проверьте условия связывания таблиц по родственным столбцам (обычно это должны быть ключевые поля). Неправильное связывание таблиц обычно оборачивается неправильно выведенными или неверными данными.
Вопросы и ответы
При связывании таблиц должны ли они связываться в том же порядке, в каком они указаны в выражении ключевого слова FROM?
Нет, но не следует забывать, что от порядка перечисления таблиц в выражении ключевого слова FROM и от порядка, в котором связаны таблицы, может зависеть скорость выполнения запроса.
При использовании связующей таблицы для связывания пары таблиц, не имеющих общих столбцов, обязательно ли выбирать в запросе хотя бы один из ее столбцов?
Нет, использование в операторе запроса связующей таблицы не обязывает отображать данные ее столбцов.
Можно ли связывать в запросе не один, а несколько столбцов таблиц?
Да, чтобы обеспечить необходимое соответствие данных, вполне вероятно, что в запросе может понадобиться связывание нескольких столбцов таблиц.
Практикум
Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".
Тесты
1. Какой тип связывания таблиц используется в запросе тогда, когда необходимо извлечь записи одной таблицы независимо от наличия или отсутствия соответствующих записей в другой?
2. Какая часть оператора SQL задает условия связывания таблиц?
3. Какой тип связывания используется тогда, когда необходимо задать эквивалентность строк связываемых таблиц?
4. Что будет, если в запросе указать выборку из двух таблиц, но не связать их?
5. Рассмотрите следующие таблицы.
ORDERS_TBL
ORD_NUM VARCHAR2(10) NOT NULL Ключевое поле
CUST_ID VARCHAR2(10) NOT NULL
PROD_ID VARCHAR2(10) NOT NULL
QTY NUMBER(6) NOT NULL
ORD_DATE DATE
PRODUCTS TBL
PROD_ID VARCHAR2CLO) NOT NULL Ключевое поле
PROD_DESC VARCHAR2(40) NOT NULL
COST NUMBER (6,2) NOT NULL
Правильно ли составлен следующий оператор, если предполагалось внешнее связывание этих таблиц?
SELECT C.CUST_ID, C.CUST_NAME, О.ORD_NUM
FROM CUSTOMERJTBL С, ORDERS_TBL 0
WHERE C.CUST_ID{+) = O.CUST_ID(+)
Упражнения
Выполните упражнения для следующих таблиц.
EMPLOYEE TBL
EMP ID VARCHAR2(9) NOT NULL Ключевое поле
LAST NAME VARCHAR2(i5) NOT NULL
FIRST NAME VARCHAR2(15) NOT NULL
MIDDLE NAME VARCHAR2 ( 15 }
ADDRESS VARCHAR2(30) NOT NULL
CITY VARCHAR2(15) NOT NULL
STATE CHAR (2) NOT NULL
ZIP NUMBER (5) NOT NULL
PHONE CHAR (10)
PAGER CHAR (10)
EMPLOYEE PAY TBL
EMP ID VARCHAR2O) NOT NULL Ключевое поле
POSITION VARCHAR2U5) NOT NULL
DATE HIRE DATE PAY RATE NUMBER (4,2) NOT NULL
DATE LAST-RAISE DATE SALARY NUMBER (6,2)
BONUS NUMBER (4,2)
CONSTRAINT EMP FK FOREIGN KEY (EMP ID) REFERENCED EMPLOYEE TBL (EMP ID)
CUSTOMERS TBL
CUST ID CUST NAME CUST ADDRESS CUST CITY
CUST STATE CUST ZIP CUST PHONE CUST_FAX
VARCHAR2 (10) VARCHAR2 (30) VARCHAR2 (20) VARCHAR2 (15) CHAR ( 2 ) NUMBER (5) NUMBER (10) NUMBER (10)
NOT NULL NOT NULL NOT NULL NOT NULL NOT NULL NOT NULL
Ключевое поле
ORDERS TBL
ORD NUM CUST ID PROD ID QTY ORD DATE
VARCHAR2 (10) VARCHAR2 (10) VARCHAR2(10) NUMBER (6) DATE