Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по Delph_nov11.doc
Скачиваний:
9
Добавлен:
01.04.2025
Размер:
2.45 Mб
Скачать

Вложенные запросы.

Результаты, возвращаемые оператором Select, можно использовать в другом операторе Select. Причем это относится и к операторам, возвращающим совокупные характеристики, и к операторам, возвращающим множество значений. Например, узнать фамилию самого молодого слушателя можно с помощью вложенных запросов:

SELECT fam, datar from osndan where datar=(SELECT max(datar) from osndan)

В этом операторе второй вложенный оператор SELECT max(datar) from osndan возвращает максимальную дату рождения, который используется в элементе WHERE основного оператор SELECT для поиска слушателя или слушателей, чья дата рождения совпадает с максимальной.

В условиях, содержащих вложенные операторы SELECT, может использоваться ключевое слово EXISTS, которое означает отбор только тех записей, для которых вложенный запрос возвращает одно или более значений. Например, оператор

Select fam, im,otch from osndan where exists (select kod_opl from opl where opl.tn=osndan.tn )

Вернет список только тех слушателей, которые имею оплату за обучение.

Объединение таблиц.

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

SELECT osndan.fam, osndan.im, osndan.otch, pasp.npasp, pasp.datav, pasp.kemv

FROM osndan, pasp

WHERE osndan.tn=pasp.tn

В нем мы обращаемся сразу к двум таблицам Osndan и Pasp, которые перечисляются через запятую сразу после ключевого слова FROM. Поэтому каждое имя поля предваряется ссылкой на таблицу, к которой оно относится. В конструкции WHERE условие osndan.tn=pasp.tn ищет запись в таблице pasp, в которой поле tn совпадает с полем tn в таблице osndan.

В операторах, работающих с несколькими таблицами, обычно каждой таблице дается псевдоним, сокращающий ссылки на таблицы. Псевдоним таблицы может записываться в списке таблиц после слова FROM, отделяясь от имени таблицы пробелом. Например, приведенный выше оператор может быть переписан следующим образом:

SELECT a.fam, a.im, a.otch, b.npasp, b.datav, b.kemv

FROM osndan a, pasp b

WHERE a.tn=b.tn

В этом примере таблице osndan дан псевдоним a, таблице pasp дан псевдоним b. Конечно, эти псевдонимы действуют только в данном операторе и не имеют никакого отношения к псевдонимам баз данных, которые мы постоянно используем.

Например, вывести в запросе фамилию, имя, отчество, курс, форму обучения и специальность слушателей можно следующим образом:

SELECT a.fam, a.im, a.otch, b.kurs, c.name_fob,d.name_spec

FROM osndan a, obuch b,fob c,spec d

WHERE a.tn=b.tn

AND b.kod_fob=c.kod_fob

AND b.kod_spec=d.kod_spec

В этом запросе один и тот же слушатель выведется столько раз сколько у него существует записей в таблице Obuch. Для того чтобы вывести в запросе фамилию, имя, отчество, курс, форму обучения и специальность слушателей, но при этом слушатель будет выводится один раз с указанием последнего (максимального) курса обучения можно использовать вложенный запрос:

SELECT a.fam, a.im, a.otch, b.kurs, c.name_fob,d.name_spec

FROM osndan a, obuch b,fob c,spec d

WHERE a.tn=b.tn

AND b.kod_fob=c.kod_fob

AND b.kod_spec=d.kod_spec

AND b.kurs=(select max(kurs) from obuch where tn=a.tn)

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

SELECT a.fam, a.im, a.otch, b.fam, b.im, b.otch, a.datar

FROM osndan a, osndan b

WHERE a.datar=b.datar

and a.tn<>b.tn

В этом примере для таблицы osndan мы ввели два псевдонима a и b. В конструкции WHERE мы ищем в этих якобы разных таблицах записи с одинаковыми датами рождения. Второе условие a.tn<>b.tn нужно, чтобы обучающийся не отображался в результатах как ровесник сам себя. Правда, приведенный оператор выведет в результате по две записи на каждую пару ровесников, сначала, например, «Николаев – Андреев», а потом «Андреев – Николаев». Чтобы исключить такое дублирование можно добавить еще одно условие - and a.tn<b.tn :

SELECT a.fam, a.im, a.otch, b.fam, b.im, b.otch, a.datar

F ROM osndan a, osndan b

WHERE a.datar=b.datar

and a.tn<>b.tn

and a.tn<b.tn

До сих пор мы рассматривали объединения, основанные на однозначном соответствии записей двух таблиц, когда каждой записи в первой таблице находилась соответствующая ей запись во второй таблице (т.е. пересечение таблиц). Возможны и другие виды объединений, которые выдают записи не зависимо от того, есть ли соответствующее поле во второй таблице. Это внешние объединения (outer join). Их три типа: левое, правое и полное. Левое объединение (обозначается ключевыми словами LEFT JOINON) включают в результат все записи первой таблицы, даже те, для которых не имеется соответствия во второй. Правое объединение (обозначается ключевыми словами RIGHT JOINON) включают в результат все записи второй таблицы, даже те, для которых не имеется соответствия в записях первой. Полное объединение (обозначается ключевыми словами FULL JOINON) включают в результат объединение записей обеих таблиц, независимо от их соответствия. Пусть, например, у Вас есть таблица обучающихся osndan и таблица оплат за обучение opl. Тогда оператор

SELECT a.fam, a.im, a.otch, b.sym_opl, b.data_opl

FROM osndan a LEFT JOIN opl b ON a.tn=b.tn

Выдаст результат вида:

Поля таблицы osndan

Поля таблицы opl

Иванов

Иван

Иванович

100 000

14.09.2003

Сидоров

Сергей

Юрьевич

150 000

12.09.2003

Петрова

Екатерина

Павловна

100 000

15.10.2003

Петров

Петр

Петрович

В этом запросе число строк соответствует числу записей таблицы osndan. В строках, относящихся к записям, для которых в таблице opl не нашлось соответствие, поля таблицы opl остаются пустыми (NULL).

Оператор

SELECT a.fam, a.im, a.otch, b.sym_opl, b.data_opl

FROM osndan a LEFT JOIN opl b ON a.tn=b.tn

WHERE a.sex=’M

Выдаст результат вида:

Поля таблицы osndan

Поля таблицы opl

Иванов

Иван

Иванович

100 000

14.09.2003

Сидоров

Сергей

Юрьевич

150 000

12.09.2003

Петров

Петр

Петрович

В этом запросе выведены только мужчины

Оператор

SELECT a.fam, a.im, a.otch, b.sym_opl, b.data_opl

FROM osndan a LEFT JOIN opl b ON a.tn=b.tn

WHERE a.sex=’M’ AND b.sym_opl IS NULL

Выдаст результат вида:

Поля таблицы osndan

Поля таблицы opl

Петров

Петр

Петрович

В этом запросе выведены только мужчины без оплат.