552 Глава 10

При работе в условии WHERE с множествами записей можно использовать
ключевые слова: All и Any. All означает, что условие выполняется для всех запи-
сей, a Any — хотя бы для одной записи. Например, оператор

Select * FROM Pers WHERE Year_b >= ALL (SELECT Year_b FROM Persi)

ищет сотрудников в Pers, которые не старше любого сотрудника в Persi. Кстати,
если в этом операторе заменить Persi на Pers, то получим список самых молодых
сотрудников организации, который мы получали ранее другим способом. А опера-
тор

Select * FROM Pers WHERE Year_b > ANY (SELECT Year_b FROM Persi)

ищет сотрудников в Pers, которые моложе хотя бы одного сотрудника в Persi.

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

SELECT Num, Fam, Year_b FROM Pers pi
WHERE EXISTS (Select Num, Year_b FROM Pers p2
WHERE (pl.Year_b = p2.Year_b) and
(pi.Num != p2.Num))

вернет список сотрудников, которые имеют хотя бы одного сверстника.

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

SELECT Num, Fam, Year_b From Pers pi
WHERE SINGULAR(Select Num, Year_b FROM Pers p2
WHERE pl.Year_b = p2.Year_b)

вернет список сотрудников, которые не имеют ни одного сверстника (год рождения
которых совпадает только с собственным годом рождения и больше не повторяется
в таблице).

10.1.2.4 Объединения таблиц

В запросе можно объединить данные двух или более таблиц. Пусть, например,
вы хотите получить список сотрудников всех производственных подразделений. В
таблице Pers мы имеем список сотрудников с указанием в поле Dep подразделе-
ний, в которых они работают. А в таблице Dep мы имеем список всех подразделе-
ний в поле Dep и характеристику каждого подразделения в поле Prosv (true, если
подразделение производственное). Тогда получить список сотрудников всех произ-
водственных подразделений можно оператором:

Select Pers.* FROM Pers, Dep WHERE
(Pers.Dep=Dep.Dep)AND(Dep.Proisv=true)

В нем мы обращаемся сразу к двум таблицам Pers и Dep, которые перечисле-
ны после ключевого слова FROM. Поэтому каждое имя поля предваряется ссыл-
кой на таблицу, к которой оно относится. Впрочем, это надо делать только для по-
лей, имя которых повторяется в разных таблицах (поле Dep). Перед полем Proisv
ссылку на таблицу можно опустить. В конструкции WHERE условие
Pers.Dep=Dep.Dep ищет запись в таблице Dep, в которой поле Dep совпадает с по-
лем Dep текущей записи таблицы Pers. А условие Dep.Proisv=true отбирает те за-
писи, в которых в таблице Dep найденному подразделению соответствует поле Pro-
isv = true.

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