- •Лекция №1 Введение. Основные понятия.
- •Субд ms Access
- •Лекция 2. Системы управления бд
- •1. Файловые системы.
- •2. История развития.
- •3. Функции субд
- •4. Типовая организация современной субд
- •5. Архитектура многопользовательских субд.
- •Лекция №3 Процесс разработки бд.
- •Логическая структура бд преобразуется в физическую с учетом аспектов производительности. Элементы модели "сущность-связь"
- •Основные понятия er-диаграмм
- •Пример разработки простой er-модели
- •Концептуальные и физические er-модели
- •Лекция №4 Реляционная модель данных
- •Аномалии отношений
- •Лекция №5 Нормализация отношений
- •4Нф (Четвертая Нормальная Форма)
- •Лекция №6 Реляционная алгебра.
- •Типы данных.
- •Создание таблиц.
- •Команды модификации.
- •Встроенные функции
- •Группировка и агрегаты.
- •Связи между таблицами.
- •Операторы работы с множествами
- •Подзапросы.
- •Условная логика
- •Представления и хранимые процедуры и триггеры.
- •Конструкция while
- •Транзакции и типы хранилищ бд.
- •Тестирование производительность InnoDb и MyIasm
- •Применение
- •Индексы.
- •1. Чтение данных с диска
- •2. Поиск данных в MySql
- •3. Сортировка данных
- •4. Выбор индексов в MySql
- •Уникальные индексы
- •5. Составные индексы
- •Устройство составного индекса
- •Поиск по диапазону
- •Сортировка
- •6. Использование explain для анализа индексов
- •Когда создавать индексы?
- •Администрирование сервера.
- •Разделение прав пользователей;
Подзапросы.
Подзапрос (subquery) – это запрос, содержащийся в другом SQL-выражении. Подзапрос всегда заключен в круглые скобки и обычно выполняется до содержащего выражения. Как и любой другой запрос, подзапрос возвращает таблицу, которая может состоять из:
• Одной строки с одним столбцом
• Нескольких строк с одним столбцом
• Нескольких строк и столбцов
Тип возвращаемой подзапросом таблицы определяет, как можно ее использовать и какие операторы можно применять в содержащем выражении для взаимодействия с этой таблицей. По завершении выполнения содержащего выражения таблицы, возвращенные любым подзапросом, выгружаются из памяти. Таким образом, подзапрос действует как временная таблица, областью видимости которой является выражение (т. е. после завершения выполнения выражения сервер высвобождает всю память, отведенную под результаты подзапроса). Рассмотрим на примерах.
Примеры посмотрим на БД Поставки.
Таблица Поставки
ID |
Дата |
Город |
Клиент |
Вес |
Объем |
Водитель |
1 |
2016-10-28 |
1 |
1 |
130 |
6 |
1 |
2 |
2016-10-31 |
2 |
2 |
150 |
1,3 |
1 |
3 |
2016-10-31 |
1 |
3 |
100 |
2 |
2 |
4 |
2016-10-31 |
1 |
2 |
120 |
2,5 |
3 |
5 |
2016-10-31 |
1 |
3 |
101 |
3 |
4 |
6 |
2016-10-29 |
2 |
3 |
103 |
3,3 |
4 |
7 |
2016-10-30 |
1 |
2 |
150 |
4 |
4 |
8 |
2016-10-28 |
2 |
2 |
160 |
0,2 |
5 |
9 |
2016-10-30 |
1 |
3 |
200 |
5 |
5 |
10 |
2016-10-29 |
3 |
1 |
100 |
8 |
1 |
Таблица Города Таблица Клиенты
ID |
Наименование |
1 |
Москва |
2 |
Челябинск |
3 |
Копейск |
ID |
Наименование |
1 |
Авангард |
2 |
Барс |
3 |
Транс-сити |
Таблица Водители
ID |
Наименование |
МаксимальныйВес |
1 |
Иванов |
150 |
2 |
Петров |
100 |
3 |
Сидоров |
120 |
4 |
Лосев |
150 |
5 |
Чуркин |
200 |
Подзапрос может быть размещен в блоке WHERE:
Предположим мы знаем водителя, но не знаем его ID, тогда мы можем получить информацию о поставках с помощью подзапроса:
SELECT *
FROM Поставки
WHERE Водитель = (
SELECT ID
FROM Водители
WHERE Водители.Наименование = 'Сидоров'
);
Подзапрос с агрегатными функциями:
Получим отгрузки, объемом выше среднего. В данном случае наш подзапрос возвращает только одно значение – средний объем всех отгрузок.
SELECT *
FROM Поставки
WHERE Поставки.Объем >= (
SELECT AVG(Поставки.Объем)
FROM Поставки
);
Если возникают какие-нибудь вопросы по поводу того, что делает подзапрос, можно выполнить его отдельно (без скобок) и посмотреть, что он возвращает.
Использование оператора IN в подзапросе. Что если подзапрос возвращает несколько строк в результате?
Оператор IN определяет допустимый набор значений.
Пример, получим информацию о поставках тех водителей, чьи автомобили имеют максимальный вес больше 120кг.
SELECT *
FROM Поставки
WHERE Водитель IN (
SELECT ID
FROM Водители
WHERE Водители.МаксимальныйВес >= 150
);
Подзапрос можно поместить в блок HAVING
Подзапрос в предложении SELECT
SELECT Водители.Наименование, (SELECT AVG(Поставки.Вес) FROM Поставки)
FROM Водители;
Соотнесенные подзапросы.
Запрос называется соотнесенным, когда оба, и внутренний, и внешний, запросы взаимозависимы. Это означает, что для обработки каждой записи внутреннего запроса, должна быть получена также запись внешнего запроса, т.е. внутренний запрос всецело зависит от внешнего.
SELECT Водители.Наименование FROM Водители WHERE Водители.id in (SELECT Поставки.Водитель FROM Поставки WHERE Водители.id = Поставки.Водитель);
Вложенный запрос будет выполняться отдельно для каждой строки внешнего запроса.
Подзапросы также можно использовать и в предложении FROM, т.е. соединять одну таблицу с временной таблицей, созданной подзапросом.
Например рассмотрим отношения Отделы(id, наименование) и Сотрудники (id, ФИО, ДатаРождения, id_Отдел). Как получить количество сотрудников для каждого отдела?
SELECT Отделы.id, Отделы.Наименование, e_cnt.how_many
FROM Отделы INNER JOIN
(SELECT id_Отдел, COUNT(*) how_many
FROM Сотрудники
GROUP BY id_Отдел) e_cnt
ON Отделы.id = e_cnt.id_Отдел;
Подзапросы для модификации данных.
Обновление данных
UPDATE Поставки
SET Город = (SELECT id FROM Города WHERE Наименование = 'Челябинск');
Команда UPDATE – обновляет данные столбца. Общий вид команды:
UPDATE <имя таблицы>
SET {имя столбца = {выражение для вычисления значения столбца
| NULL
| DEFAULT},...}
[ {WHERE <предикат>}];
Удаление данных.
Оператор DELETE удаляет строки из временных или постоянных базовых таблиц, представлений или курсоров, причем в двух последних случаях действие оператора распространяется на те базовые таблицы, из которых извлекались данные в эти представления или курсоры. Оператор удаления имеет простой синтаксис:
DELETE FROM <имя таблицы > [WHERE <предикат>];
Если предложение WHERE отсутствует, удаляются все строки из таблицы или представления (представление должно быть обновляемым).
Здесь также можно воспользоваться подзапросами.
DELETE FROM Поставки
WHERE Водитель = (SELECT id FROM Водители WHERE Наименование = 'Сидоров');
