- •Глава 1. Историческая справка. 10
- •Глава 2. Пример бд «Ресторан». 20
- •Глава 3. Выборка данных. 25
- •Глава 4. Подзапросы и производные таблицы 65
- •Глава 5. Функции ранжирования. 86
- •Глава 1. Историческая справка.
- •Стандарты.
- •1.2. Структура sql.
- •Глава 2. Пример бд «Ресторан».
- •2.1. Описание.
- •2.2. Диаграмма.
- •2.3. Данные в таблицах.
- •Глава 3. Выборка данных.
- •3.1. Оператор select. Синтаксис.
- •3.2. Примеры запросов с использованием единственной таблицы.
- •3.2.1. Выборка без использования фразы where.
- •3.2.1.1. Простейшие примеры.
- •3.2.1.2. Исключение дубликатов (distinct).
- •3.2.1.3. Выборка вычисляемых значений.
- •3.2.2. Выборка c использованием фразы where.
- •3.2.2.1. Использование операторов сравнения.
- •3.2.2.2. Сравнение с null.
- •3.2.2.3. Использование between.
- •3.2.2.4. Использование in (not in).
- •3.2.2.5. Использование like.
- •3.2.2.6. Выборка с упорядочением.
- •3.2.3. Использование агрегатных функций для подведения итогов.
- •3.2.3.1. Агрегатные функции без использования фразы group by.
- •3.2.3.2. Фраза group by.
- •3.2.3.3. Раздел having.
- •3.3. Примеры запросов с использованием нескольких таблиц.
- •3.3.1. Соединения «с условием where».
- •3.3.2. Соединение таблиц с дополнительными условиями.
- •3.3.2.1. Соединение таблицы со своей копией.
- •3.4. Соединения нескольких таблиц, используя join.
- •3.4.1. Внутреннее соединение.
- •3.4.2. Внешнее соединение.
- •3.4.2.1. Левое внешнее соединение.
- •3.4.2.2. Правое внешнее соединение.
- •3.4.2.3. Полное внешнее соединение.
- •3.4.2.4. Перекрёстное соединение.
- •3.4.3. Реальные примеры соединений.
- •Isnull(cast(n.Количество as varchar), ’нет’) as на_складе
- •Isnull(cast(n.Количество as varchar),’нет’) as на_складе
- •Глава 4. Подзапросы и производные таблицы
- •4.1.Производная таблица.
- •4.2. Вложенные подзапросы
- •4.2.1 Простые вложенные подзапросы
- •4.2.2. Использование одной и той же таблицы во внешнем и вложенном подзапросе
- •4.2.3. Использование агрегатных функций в подзапросах.
- •4.2.4. Подзапросы в предложении having.
- •4.3. Соотнесенные подзапросы.
- •4.4 Использование оператора exists.
- •4.5. Использование операторов any и all.
- •4.6. Объединение запросов union.
- •4.6.1. Union и устранение дубликатов.
- •4.6.2. Использование строк и выражений с union.
- •4.6.3. Использование union с order by.
- •4.6.4. Реализация внешнего полного соединения через запросы с union.
- •Глава 5. Функции ранжирования.
- •5.1. Функция row_number.
- •5.2. Функции rank() и dense_rank()
- •Глава 6. ИспользованиеPivoTиUnpivot.
- •In ([Овощи], [Мясо], [Рыба], [Молоко], [Яйца], [Крупа], [Фрукты], [Кофе])
- •In ( [первый сведенный столбец], [второй сведенный столбец],
- •In ([Овощи], [Мясо], [Рыба], [Молоко], [Яйца], [Крупа], [Фрукты], [Кофе])
- •Insert into Продукты (id_Продукта, Продукт, Белки)
- •Values (18, 'Горох', 180 );
- •Insert into Продукты (Продукт, Белки, Жиры)
- •7.4. Оператор update.
- •Глава 8. Представление.
- •Insert into Список_блюд values (36, 'Рагу', 3, 20);
- •Глава 9. Создание, изменение и удаление таблиц.
- •9.1. Оператор create table
- •6. Ограничение identity (автоинкрементное поле).
- •9.2. Изменение таблицы после того как она была создана (alter table).
- •9.3. Удаление таблицы (drop table).
- •9.4. Операторы создания и удаления индексов.
- •9.5. Понятие домена
- •Глава 10. Обобщенные табличные выражения (сте).
- •Представления, производные таблицы и выражения cte.
- •Рекурсивные запросы.
- •Id_father integer foreign key references Tree (id),
- •Values (1, null, 'all'), (2, 1, 'sea'), (3, 1, 'earth'),
- •Деревья без рекурсии.
- •Пример использования сте для решения задачи Коммивояжера.
- •Insert into tur select to_town, from_town, miles from tur;
- •Глава 11. Этапы выполнения командыSql.
- •11.1. Оптимизация запросов.
- •Приложение 1. Реализация реляционной алгебры средствами оператора select (Реляционная полнота sql).
- •Intersect
- •Рекомендуемая литература
4.3. Соотнесенные подзапросы.
Соотнесенным называется подзапрос, который ссылается на данные внешнего запроса. Соотнесенный подзапрос - один из большого количества тонких понятий в SQL из-за сложности в его оценке. Если вы сумеете овладеть им, вы найдете что он очень мощный, потому что может выполнять сложные функции с помощью очень лаконичных указаний. Соотнесенный подзапрос выполняется неоднократно, по одному разу для каждой строки таблицы основного запроса.
Пример 31.
Рассчитать стоимость блюд на основе молока.
SELECT b.Блюдо, ( SELECT SUM (s.Вес*n.Цена/1000)
FROM Состав s JOIN Наличие n ON s.Продукт = n.Продукт
WHERE s.Блюдо = b.ID_Блюда) + b.Труд as Стоимость
FROM Блюда b
WHERE Основа = 'Молоко';
Результат |
|
Блюдо |
Стоимость |
Сметана |
28,2671 |
Творог |
19,9821 |
Суп молочный |
35,9746 |
Сырники |
25,0069 |
Вареники ленивые |
24,1267 |
Суфле из творога |
36,7818 |
Крем творожный |
22,8368 |
Молочный напиток |
45,4615 |
Такой подзапрос отличается от рассмотренного выше, тем, что вложенный подзапрос не может быть обработан прежде, чем будет обрабатываться внешний подзапрос. Это связано с тем, что вложенный подзапрос зависит от значения b.ID_Блюда, а оно изменяется по мере того, как система проверяет различные строки таблицы Блюда. Следовательно, с концептуальной точки зрения обработка осуществляется следующим образом:
Система проверяет первую строку таблицы Блюда. Предположим, что это строка удовлетворяет условию Основа = 'Молоко'
Теперь система может передать b.ID_Блюда в подзапрос и вычислить стоимость блюда.
Далее система будет повторять обработку такого рода для следующего блюда и т.д. до тех пор, пока не будут рассмотрены все строки таблицы Блюда.
Рассмотрим пример использования одной и той же таблицы во внешнем подзапросе и соотнесенном вложенном подзапросе.
Пример 32.
Выдать номера всех продуктов, которые используются только в одном блюде.
SELECT С1.Продукт
FROM Состав С1
WHERE С1.Продукт NOT IN (SELECT С2.Продукт
FROM Состав С2
WHERE С2.Блюдо <> С1.Блюдо);
Данный запрос возвращает пустую таблицу, так нет таких продуктов в БД.
Действие этого запроса можно пояснить следующим образом: "Поочередно для каждой строки таблицы Состав, скажем С1, выделить значение номера продукта (С1.Продукт) и номер блюда (С1.Блюдо), в котором этот продукт используется. А затем проверить, не встречается ли этот продукт в списке продуктов (С2) необходимых для приготовления других блюд (<>С1.Блюдо). Если не встречается, то выводим его".
Отметим, что в этой формулировке должен быть использован по крайней мере один псевдоним - либо С1, либо С2.
Данный запрос может быть реализован и по-другому.
SELECT Продукт
FROM Состав
GROUP BY Продукт
HAVING COUNT (DISTINCT Блюдо) = 1;
Для проверки правильности выводов данных запросов можно выполнить команду:
Результат |
|
Продукт |
|
1 |
5 |
2 |
5 |
3 |
19 |
4 |
4 |
5 |
11 |
6 |
10 |
7 |
11 |
8 |
6 |
9 |
7 |
10 |
8 |
11 |
8 |
12 |
13 |
13 |
5 |
14 |
8 |
15 |
9 |
16 |
17 |
17 |
2 |
FROM Состав
GROUP BY Продукт;
И получить результат: