ВУЗ: Томский государственный университет систем управления и радиоэлектроники
Категория: Учебное пособие
Дисциплина: Базы данных
Добавлен: 28.11.2018
Просмотров: 5434
Скачиваний: 10
76
Запрос
:
Вывести
фамилии
штукатуров
,
кровельщиков
.
SELECT *
FROM
Работник
WHERE
Специальность
IN ('
штукатур
', '
кровельщик
')
Результат
:
№
рабо
-
Фамилия
Недельная
Специальность
тника
зарплата
1412
К
.
Иванов
13.75
штукатур
2920
Р
.
Смирнов
10.00
кровельщик
1520
Г
.
Сидоров
11.75
штукатур
Этот
запрос
поясняет
использование
оператора
сравне
-
ния
IN (
В
).
Условие
WHERE
считается
истинным
,
если
тип
специальности
строки
расположен
внутри
множества
,
указан
-
ного
в
скобках
,
то
есть
если
тип
специальности
–
штукатур
,
кровельщик
Предположим
,
что
мы
не
можем
точно
вспомнить
напи
-
сание
специальности
: «
электрик
»
или
«
электронщик
»
или
еще
как
-
то
.
Символы
шаблона
,
которые
замещают
неопре
-
деленные
строки
символов
,
облегчают
поиск
неточного
на
-
писания
в
запросе
.
Запрос
:
Вывести
фамилии
работников
,
чей
тип
специ
-
альности
начинается
с
«
элек
».
SELECT *
FROM
Работник
WHERE
Специальность
LIKE ('
элек
%')
Результат
:
№
рабо
-
Фамилия
Недельная
Специальность
тника
зарплата
1235
И
.
Петров
12.50
электрик
1311
Х
.
Васильев
15.50
электрик
77
В
SQL
есть
два
символа
шаблона
: % (
процент
)
и
_ (
под
-
черкивание
).
Подчеркивание
замещает
ровно
один
неопре
-
деленный
символ
.
Процент
замещает
произвольное
число
символов
,
начиная
с
нуля
.
Когда
используются
символы
шаблона
,
для
сравнения
символьных
переменных
с
констан
-
тами
требуется
оператор
LIKE (
как
).
5.2.
Многотабличные
запросы
Возможность
связывать
элементы
данных
вне
границ
од
-
ной
таблицы
важна
для
любого
языка
баз
данных
. SQL
связывает
данные
разных
таблиц
аналогично
тому
,
как
это
делает
операция
соединения
реляционной
алгебры
.
Рас
-
смотрим
запрос
.
Запрос
:
Вывести
специальности
рабочих
,
назначенных
на
здание
435.
Данные
,
необходимые
для
ответа
,
находятся
в
двух
таб
-
лицах
: «
Работник
»
и
«
Работа
».
Для
решения
в
SQL
требу
-
ется
перечислить
обе
таблицы
в
команде
FROM
и
задать
специальный
тип
условия
WHERE:
SELECT
Специальность
FROM
Работник
,
Работа
WHERE
Работник
.
№
работника
=
Работа
.
№
работника
AND
№
здания
= 435
Рассмотрим
два
этапа
обработки
системой
данного
за
-
проса
.
1.
Сначала
обрабатывается
фраза
FROM.
Однако
в
этом
случае
,
поскольку
в
команде
указаны
две
таблицы
,
система
создает
декартово
произведение
строк
этих
таблиц
.
Если
в
команде
FROM
перечислено
более
двух
таблиц
,
то
создает
-
ся
декартово
произведение
всех
таблиц
,
указанных
в
ко
-
манде
.
2.
После
создания
гигантской
реляционной
таблицы
сис
-
тема
применяет
команду
WHERE.
Каждая
строка
таблицы
,
созданной
командой
FROM,
проверяется
на
выполнение
ус
-
ловия
WHERE.
Строки
,
не
удовлетворяющие
условию
,
ис
-
ключаются
из
рассмотрения
.
Затем
к
оставшимся
строкам
применяется
фраза
SELECT.
Фраза
WHERE
в
данном
запросе
содержит
два
условия
:
1. WHERE
Работник
.
№
работника
=
Работа
.
№
работника
2.
№
здания
= 435
78
Первое
из
этих
условий
–
условие
соединения
.
Так
как
обе
таблицы
содержат
столбец
с
именем
«
№
работника
»,
их
декартово
произведение
будет
содержать
два
столбца
с
таким
именем
.
Для
того
чтобы
различить
их
,
помещаем
пе
-
ред
именем
столбца
имя
исходной
таблицы
,
отделяя
его
точкой
.
Полное
соединение
этих
двух
таблиц
представлено
на
рис
. 7.2.
№
рабо
-
Фамилия
Недельная
Специальность
тника
зарплата
1412
К
.
Иванов
13.75
штукатур
1235
И
.
Петров
12.50
электрик
Работа
№
работника
№
здания
Дата
_
начала
Число
_
дней
1412 435 15.10 15
1235 435 17.10 22
Рис
. 5.2.
Соединение
таблиц
«
Работник
»
и
«
Работа
»
Результат
:
штукатур
электрик
В
SQL
можно
за
один
раз
связать
более
двух
таблиц
:
Запрос
:
Вывести
фамилии
работников
,
назначенных
на
здания
офисов
.
SELECT
Фамилия
FROM
Работник
,
Работа
,
Здание
WHERE
Работник
.
№
работника
=
Работа
.
№
работника
AND
Работа
.
№
здания
=
Здание
.
№
здания
AND
Тип
= '
офис
'
Результат
:
Фамилия
И
.
Петров
79
Команды
SQL
этого
запроса
создают
одну
таблицу
из
трех
реляционных
таблиц
БД
.
Первые
две
таблицы
созда
-
ются
по
«
№
работника
»,
после
чего
к
полученной
таблице
присоединяется
третья
таблица
по
«
№
здания
».
Условие
«
Тип
= '
офис
'«
команды
WHERE
приводит
к
исключению
всех
строк
,
кроме
относящихся
к
офисным
зданиям
.
Это
соответ
-
ствует
требованиям
запроса
.
5.3.
Подзапросы
Подзапрос
может
помещаться
в
команду
WHERE
запро
-
са
,
в
результате
чего
возможности
команды
WHERE
расши
-
ряются
.
Рассмотрим
пример
.
Запрос
:
Вывести
специальности
рабочих
,
назначенных
на
здание
435?
SELECT
Специальность
FROM
Работник
WHERE
№
работника
IN
(SELECT
№
работника
FROM
Работа
WHERE
№
здания
= 435 )
Подзапрос
в
этом
примере
(SELECT
№
работника
FROM
Работа
WHERE
№
здания
= 435 )
Запрос
,
в
котором
содержится
подзапрос
,
называется
внешним
запросом
или
главным
запросом
.
Подзапрос
при
-
водит
к
созданию
следующего
множества
№
работников
:
№
Работника
1412
1235
Затем
это
множество
«
№
Работников
»
занимает
место
подзапроса
во
внешнем
запросе
.
С
этого
момента
выполня
-
ется
внешний
запрос
,
использующий
множество
,
созданное
подзапросом
.
Внешний
запрос
обрабатывает
каждую
строку
таблицы
«
Работник
»
в
соответствии
с
условием
WHERE.
Если
«
№
работника
»
строки
лежит
во
множестве
,
созданном
80
подзапросом
,
то
«
Специальность
»
строки
выбирается
и
вы
-
водится
в
результирующей
таблице
:
Специальность
Штукатур
Электрик
Очень
важно
,
что
фраза
SELECT
подзапроса
содержит
«
№
работника
»
и
только
«
№
работника
.
В
противном
случае
фраза
WHERE
внешнего
запроса
,
означающая
,
что
«
№
ра
-
ботника
»
лежит
в
множестве
«
№
работников
»,
не
имела
бы
смысла
.
Подзапрос
может
логично
выполняться
прежде
,
чем
хотя
бы
одна
строка
рассматривается
главным
запросом
.
В
неко
-
тором
смысле
подзапрос
независим
от
главного
запроса
.
Он
может
выполняться
как
полноценный
запрос
.
Такой
подза
-
прос
называется
некоррелированным
подзапросом
.
Приведем
пример
подзапроса
внутри
подзапроса
.
Запрос
:
Вывести
фамилии
работников
,
назначенных
на
здания
офисов
.
SELECT
Фамилия
FROM
Работник
WHERE
№
работника
IN
(SELECT
№
работника
FROM
Работа
WHERE
№
здания
IN
(SELECT
№
здания
FROM
Здание
WHERE
Тип
= '
Офис
' ))
Результат
:
Фамилия
И
.
Петров
Нигде
не
нужно
указывать
перед
именами
столбцов
име
-
на
таблиц
,
поскольку
каждый
подзапрос
обрабатывает
одну
и
только
одну
таблицу
,
так
что
никаких
неопределенностей
возникнуть
не
может
.
Выполнение
запроса
происходит
в
по
-
рядке
изнутри
наружу
.