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

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

WHERE таблица1.столбец(+) = таблица2.столбец

SQL> SELECT * FROM dept;

   DEPTNO DNAME          LOC

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

       10 ACCOUNTING     NEW YORK

       20 RESEARCH       DALLAS

       30 SALES          CHICAGO

       40 OPERATIONS     BOSTON

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

  2  FROM dept d, emp e

  3  WHERE d.deptno=e.deptno AND d.deptno>=30;

   DEPTNO DNAME          ENAME

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

       30 SALES          ALLEN

       30 SALES          BLAKE

       30 SALES          MARTIN

       30 SALES          JAMES

       30 SALES          TURNER

       30 SALES          WARD

6 rows selected.

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

  2  FROM dept d, emp e

  3  WHERE d.deptno=e.deptno(+) AND d.deptno>=30;

   DEPTNO DNAME          ENAME

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

       30 SALES          ALLEN

       30 SALES          BLAKE

       30 SALES          MARTIN

       30 SALES          JAMES

       30 SALES          TURNER

       30 SALES          WARD

       40 OPERATIONS

7 rows selected.

Соединение таблицы с самой собой

Отношения могут существовать не только между таблицами, но и внутри одно таблицы (рекурсивная связь). Например (Рисунок 3), таблица EMP содержит список сотрудников, каждый из которых может быть начальником другого сотрудника и может, в свою очередь, сам быть начальником. Если Вы хотите получить список сотрудников с указанием начальника, обычный многотабличный запрос не поможет, т.к. оба сравниваемых столбца находятся в одной таблице (EMPNO – первичный ключ для списка начальников, MGR – внешний ключ для списка сотрудников). Для выполнения такого запроса необходимо объединить таблицу саму с собой, это возможно путем имитации двух таблиц с помощью псевдонимов. Например, с помощью псевдонима m представляем таблицу EMP, как список начальников с первичным ключом на колонке EMPNO, а с помощью псевдонима e – как список сотрудников с внешним ключом на колонке MGR. Тогда мы можем составить обычный многотабличный запрос на основе эквисоединения этих двух таблиц.

Рисунок 3 Рекурсивная связь внутри таблицы

SQL> SELECT m.ename || ' is manager of ' || e.ename " "

  2  FROM emp m, emp e

  3  WHERE m.empno=e.mgr;

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

JONES is manager of SCOTT

JONES is manager of FORD

BLAKE is manager of ALLEN

BLAKE is manager of WARD

BLAKE is manager of JAMES

BLAKE is manager of TURNER

BLAKE is manager of MARTIN

CLARK is manager of MILLER

SCOTT is manager of ADAMS

KING is manager of JONES

KING is manager of CLARK

KING is manager of BLAKE

FORD is manager of SMITH

13 rows selected.

Операторы множеств

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

§  UNION – возвращает все строки, выбранные первым и вторым запросами

§  UNION ALL – возвращает все строки, включая повторяющиеся, выбранные первым и вторым запросами

§  INTERSECT – возвращает строки, выбранные и первым, и вторым запросами

§  MINUS  - возвращает строки, выбранные первым запросом, из которых исключены строки, выбранные вторым запросом

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

UNION | UNION ALL | INTERSECT | MINUS

SELECT [DISTINCT] {*, столбец [псевдоним], …} FROM таблица2 [WHERE условие]

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

SQL> SELECT * FROM emp_bonus;

ENAME      JOB           BONUS

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

SCOTT      ANALYST        3000

FORD       ANALYST        3000

STONE      ADVISER        2000

SQL> SELECT ename, job, sal FROM emp

  2  WHERE job<='CLERK';

ENAME      JOB             SAL

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

SMITH      CLERK           800

SCOTT      ANALYST        3000

ADAMS      CLERK          1100

JAMES      CLERK           950

FORD       ANALYST        3000

MILLER     CLERK          1300

6 rows selected.

SQL> SELECT * FROM emp_bonus

  2  UNION

  3  SELECT ename, job, sal FROM emp WHERE job<='CLERK';

ENAME      JOB           BONUS

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

ADAMS      CLERK          1100

FORD       ANALYST        3000

JAMES      CLERK           950

MILLER     CLERK          1300

SCOTT      ANALYST        3000

SMITH      CLERK           800

STONE      ADVISER        2000

7 rows selected.

SQL> SELECT * FROM emp_bonus

  2  UNION ALL

  3  SELECT ename, job, sal FROM emp WHERE job<='CLERK';

ENAME      JOB           BONUS

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

SCOTT      ANALYST        3000

FORD       ANALYST        3000

STONE      ADVISER        2000

SMITH      CLERK           800

SCOTT      ANALYST        3000

ADAMS      CLERK          1100

JAMES      CLERK           950

FORD       ANALYST        3000

MILLER     CLERK          1300

9 rows selected.

SQL> SELECT * FROM emp_bonus

  2  INTERSECT

  3  SELECT ename, job, sal FROM emp WHERE job<='CLERK';

ENAME      JOB           BONUS

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

FORD       ANALYST        3000

SCOTT      ANALYST        3000

SQL> SELECT * FROM emp_bonus

  2  MINUS

  3  SELECT ename, job, sal FROM emp

  4  WHERE job<='CLERK';

ENAME      JOB           BONUS

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

STONE      ADVISER        2000

SQL> SELECT * FROM emp_bonus

  2  UNION

  3  SELECT ename, job, sal FROM emp WHERE job<='CLERK'

  4  ORDER BY 1;

ENAME      JOB           BONUS

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

ADAMS      CLERK          1100

FORD       ANALYST        3000

JAMES      CLERK           950

MILLER     CLERK          1300

SCOTT      ANALYST        3000

SMITH      CLERK           800

STONE      ADVISER        2000

7 rows selected.

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

1.  Выполняется каждый оператор SELECT, участвующий в объединении.

§  Формируется декартово произведение таблиц, перечисленных в предложении FROM.

§  Условие соединения, заданное в предложении WHERE, применяется ко всем строкам декартова произведения таблиц. Строки, для которых условие соединения не выполняется, отбрасываются.

§  Для каждой из оставшихся строк вычисляется каждое значение в списке SELECT.

§  Если задано ключевое слово DISTINCT, удаляются повторяющиеся строки.

2.  Выполняется объединение, заданное оператором множеств.

3.  Если задано предложение ORDER BY, результат запроса сортируется.

Литература

1.  Джудит С.Боуман и др. Практическое руководство по SQL/ 3-е издание: пер. с англ. – К.:  Диалектика, 1997.

2.  Джеймс Р. Грофф, Пол Н. Вайнберг SQL: полное руководство: пер. с англ. - -К.: Издательская группа BHV, 1998.