Выборка данных из нескольких таблиц

Страницы работы

Содержание работы

Выборка данных из нескольких таблиц

Правила нормализации таблиц, действующие в рамках концепции реляционной модели, рекомендуют разбивать данные на множество таблиц. Следовательно, в базе данных, разработанной в соответствии с концепцией реляционной модели, информация, как правило, хранится в нескольких связанных между собой таблицах. Поэтому, для получения достаточно полной информации из такой базы данных обычно требуется извлекать данные из нескольких таблиц (Рисунок 1). SQL позволяет получать информацию из двух и более таблиц путем формирования многотабличных запросов.

Рисунок 1 Таблицы, связанные отношением «первичный ключ/внешний ключ»

Основой многотабличного запроса является объединение таблиц, получающееся в результате формирования пар строк путем сравнения содержимого соответствующих столбцов. Поэтому очень важной является задача выбора столбцов для объединения таблиц. Лучше всего для этой цели подходят столбцы, являющиеся первичным или внешним ключом. Причем, если ключ является составным, объединение можно производить по всем входящим в него столбцам. Объединение на основе отношения «первичный ключ/внешний ключ» подразумевает совместимость таблиц, что обеспечивает целостность данных.

Чтобы информация, полученная в результате многотабличного запроса, была полноценной, необходимо, чтобы сравниваемые столбцы имели одинаковые или совместимые (т.е. такие, которые можно преобразовать друг в друга) типы данных. Значения, содержащиеся в столбцах, по которым производится объединение, должны быть сравнимыми. Например, столбцы DNAME и ENAME (Рисунок 1) имеют один тип данных, но объединять таблицы на основе этих столбцов не имеет смысла, т.к. информация, полученная в результате сравнения названия отдела с фамилией сотрудника, не будет иметь никакой ценности. Имена сравниваемых столбцов могут быть разными, хотя чаще всего они совпадают. Если в столбцах, по которым производится сравнение, имеются неопределенные значения, то они пропускаются, т.к. неопределенное значение не может быть равно никакому, в том числе неопределенному, значению. Связанные столбцы можно не включать в результирующее множество, т.к. чаще всего они представляют собой идентификаторы, которые сами по себе интереса не представляют.

Основные типы объединения таблиц:

§  Эквисоединения (объединение по равенству)

§  Не-эквисоединения (объединения по неравенству)

Кроме этого существуют следующие типы объединения таблиц

§  Внешние соединения

§  Соединения с собой (самообъединения)

Все рассмотренные типы объединения таблиц могут быть получены путем составления многотабличного запроса и представляют собой объединение столбцов из разных таблиц. Если Вы хотите объединить не столбцы, а строки таблиц, многотабличный запрос Вам не поможет. В этом случае необходимо использовать операторы множеств, которые позволяют объединять строки из разных таблиц, не основываясь на сравнении значений из соответствующих столбцов.

Декартово произведение

В связи с тем, что многотабличные запросы выполняются путем сравнения столбцов, оператор SELECT должен содержать условие поиска, которое определяет соотношение столбцов. Если условие поиска опущено или недействительно, результирующее множество будет содержать все возможные комбинации пар строк из обеих таблиц (декартово произведение). В примере ниже показано декартово произведение двух таблиц: DEPT, состоящей из 4-х строк и EMP, содержащей 14 строк. Результирующее множество представляет собой таблицу, состоящую из 56 (4´14) строк.

SQL> SELECT d.deptno, dname, e.deptno, ename FROM dept d, emp e;

   DEPTNO DNAME             DEPTNO ENAME

--------- -------------- --------- ----------

       10 ACCOUNTING            20 SMITH

       20 RESEARCH              20 SMITH

       30 SALES                 20 SMITH

       40 OPERATIONS            20 SMITH

       10 ACCOUNTING            30 ALLEN

       20 RESEARCH              30 ALLEN

       30 SALES                 30 ALLEN

       40 OPERATIONS            30 ALLEN

                     …

56 rows selected.

Чтобы избежать декартова произведения, используйте условие соединения таблиц. Причем минимальное количество условий соединения  должно быть равно количеству объединяемых таблиц минус один. Это правило может не относиться к таблицам, первичный ключ которых состоит из нескольких столбцов, т.к. уникальный идентификатор строк такой таблицы предполагает несколько значений. Условия соединения, как правило, объединяются с помощью логического оператора AND, т.к. оператор OR недостаточно ограничивает объединение таблиц.

Многотабличные запросы

SELECT [DISTINCT] {*, таблица1.столбец [псевдоним], …}

FROM таблица1, таблица2, …

[WHERE условие соединения]

[ORDER BY {столбец | псевдоним | позиция} [ASC | DESC];

Для корректного построения многотабличного запроса необходимо задать условие соединения таблиц. Условие соединения указывается в предложении WHERE. Перед именами столбцов в списке SELECT рекомендуется указывать имена соответствующих таблиц. Имя таблицы отделяется точкой от имени столбца. Это правило носит рекомендательный характер в том случае, если имена столбцов, перечисленных в списке SELECT, уникальны (имеются только в одной таблице). Если Вы запрашиваете столбцы с одинаковыми именами из разных таблиц, обязательно указывайте имена таблиц перед именами столбцов.

SQL> SELECT deptno, dname, deptno, ename

  2  FROM dept, emp

  3  WHERE deptno=deptno;

WHERE deptno=deptno

             *

ERROR at line 3:

ORA-00918: column ambiguously defined

SQL> SELECT dept.deptno, dname, emp.deptno, ename

  2  FROM dept, emp

  3  WHERE dept.deptno=emp.deptno;

   DEPTNO DNAME             DEPTNO ENAME

--------- -------------- --------- ----------

       10 ACCOUNTING            10 CLARK

       10 ACCOUNTING            10 KING

       10 ACCOUNTING            10 MILLER

       20 RESEARCH              20 SMITH

       20 RESEARCH              20 ADAMS

       20 RESEARCH              20 FORD

       20 RESEARCH              20 SCOTT

       20 RESEARCH              20 JONES

       30 SALES                 30 ALLEN

       30 SALES                 30 BLAKE

       30 SALES                 30 MARTIN

       30 SALES                 30 JAMES

       30 SALES                 30 TURNER

       30 SALES                 30 WARD

14 rows selected.

Псевдонимы таблиц

Имена таблиц могут оказаться слишком длинными. В этом случае при составлении корректного запроса код SQL может оказаться очень большим, что увеличит время отклика, т.к. на обработку такого запроса понадобится больше времени. Чтобы уменьшить код SQL, и, следовательно, ускорить выполнение запроса, используйте псевдонимы вместо имен таблиц в многотабличных запросах. Использование псевдонима таблицы при однотабличном запросе может, наоборот, увеличить время отклика.

SQL> SELECT d.deptno, d.dname, e.deptno, e.ename

  2  FROM dept d, emp e

  3  WHERE d.deptno=e.deptno;

   DEPTNO DNAME             DEPTNO ENAME

--------- -------------- --------- ----------

       10 ACCOUNTING            10 CLARK

       10 ACCOUNTING            10 KING

       10 ACCOUNTING            10 MILLER

       20 RESEARCH              20 SMITH

       20 RESEARCH              20 ADAMS

       20 RESEARCH              20 FORD

Похожие материалы

Информация о работе