- •Лабораторная работа №6. «сложные запросы к базе данных. Запросы на основе нескольких таблиц. Коррелированные вложенные подзапросы»
- •6.1 Цель работы
- •6.2 Введение
- •6.3 Методика выполнения работы
- •6.4 Примерные варианты заданий
- •6.7.1 Простое объединение двух таблиц
- •6.7.2 Объединение более чем двух таблиц
- •6.5 Содержание отчета
- •1) Цель работы.
- •6.6 Контрольные вопросы
- •6.7 Рекомендации по выполнению работы
- •6.7.3 Псевдонимы и рекурсивные объединения
- •6.7.4 Вложенные подзапросы
- •6.7.5 Построение коррелированных вложенных подзапросов
- •6.7.6 Соотнесение таблицы со своей копией
- •6.7.7 Оператор (квантор) exists
- •6.7.8 Оператор any
- •6.7.9 Оператор all
- •6.7.10 Генерация отчетов с помощью компонентов QuickReport
6.5 Содержание отчета
Отчет должен содержать следующие разделы:
1) Цель работы.
2) Выполнение работы (таблицы исходных данных, тексты запросов в соответствии заданием, сформулированные на естественном языке и структурированном языке запросов SQL, результаты выполнения запросов)
3) Выводы.
Примечание. Запросы должны иметь логический смысл. Без формулировки запросов на естественном языке отчет приниматься не будет.
6.6 Контрольные вопросы
1) В чем различие соединения таблиц по условию и с использованием JOIN?
2) В чем различие вложенных запросов и запросов с соединением?
3) Какие формы записи подзапроса недопустимы?
4) В чем особенность подзапроса, перед которым стоит знак арифметического сравнения?
5) Что такое коррелированный подзапрос?
6) Опишите алгоритм выполнения запроса с коррелированным подзапросом.
7) Назначение операторов EXIST, ALL, ANY.
8) Что такое отчет? Какие средства среды Delphi (C++ Builder) используются для создания отчетов?
6.7 Рекомендации по выполнению работы
Запросы к нескольким таблицам являются наиболее часто используемым типом запросов. Реляционные БД нормализованы, и хранимая информация разбита по большому количеству таблиц.
6.7.1 Простое объединение двух таблиц
Существует два основных способа объединения таблиц – с помощью оператора JOIN языка SQL, и с помощью условия в разделе WHERE. Например, объединить таблицу Customers и таблицу Salespeople по полю city можно следующим образом:
SELECT
Customers.cname,
Salespeople.sname,
Salespeople.city
FROM
Salespeople, Customers
WHERE
Salespeople.city = Customers.city;
Для выполнения данного запроса сервер произведет декартово произведение двух таблиц, после чего выполнит операцию селекции нужных строк, затем – проекцию нужных полей. Декартово произведение – это операция, которая требует для своего выполнения максимальное количество памяти и процессорного времени, по сравнению с другими известными операциями. Данный способ неэффективен.
В случае, если мы используем оператор JOIN, запрос будет выглядеть так:
SELECT
Customers.cname,
Salespeople.sname,
Salespeople.city
FROM
Salespeople JOIN Customers ON Salespeople.city = Customers.city;
В данном случае сервер БД не будет производить декартово произведение, сервер воспользуется индексами для определения совпадающих значений поля city, выберет строки с совпадающими значениями, а затем произведет проекцию. Данная операция происходит на порядок быстрее. В случае, если по полям учавствующим в соединении, не создан индекс, сервер вынужден производить декартово произведение.
Можно сделать следующие выводы:
- если объединение таблиц происходит по ключам, выгоднее использовать JOIN;
- если запрос выполняется медленно, нужно создать индекс по полю – параметру объединения (CREATE INDEX)
6.7.2 Объединение более чем двух таблиц
Объединение более чем двух таблиц по форме не отличается от простого объединения. Например, чтобы объединить три таблицы по некоторому условию, можно записать:
SELECT onum, cname, Orders.cnum, Orders.snum
FROM Salespeople, Customers, Orders
WHERE
Customers.city <> Salespeople.city AND
Orders.cnum = Customers.cnum AND
Orders.snum = Salespeople.snum;
Тот же запрос, переписанный с использованием JOIN, выглядит более сложно:
SELECT onum, cname, Orders.cnum, Orders.snum
FROM (Orders JOIN Customers ON Orders.cnum = Customers.cnum) JOIN Salespeople ON Orders.snum = Salespeople.snum
WHERE
Customers.city <> Salespeople.city AND
