SELECT Вид,
--столбец (столбцы), значения из которого формируют заголовки строк
[Овощи], [Мясо], [Рыба], [Молоко], [Яйца], [Крупа], [Фрукты], [Кофе]
--значения формирующие заголовки столбцов
FROM (SELECT s.Вид, Основа
FROM Блюда b JOIN Справочник_вид_блюда s
ON b.Вид = s.ID_Вид) a
--здесь может быть таблица или подзапрос
PIVOT --формирование pivot-таблицы
(COUNT(Основа)
-- агрегатная функция, формирующая содержимое сводной таблицы
FOR Основа
-- указывается столбец, уникальные значения в котором будут являться
--заголовками столбцов
IN ([Овощи], [Мясо], [Рыба], [Молоко], [Яйца], [Крупа], [Фрукты], [Кофе])
--указываются конкретные значения в столбце Основа,
-- которые следует использовать в качестве заголовков
) pvt ;
-- алиас для сводной таблицы
Результат
|
|
вид
|
Овощи
|
Мясо
|
Рыба
|
Молоко
|
Яйца
|
Крупа
|
Фрукты
|
Кофе
|
Горячее
|
2
|
2
|
1
|
3
|
2
|
2
|
0
|
0
|
Десерт
|
0
|
0
|
0
|
1
|
0
|
0
|
3
|
0
|
Закуска
|
2
|
2
|
2
|
2
|
0
|
0
|
0
|
0
|
Напиток
|
0
|
0
|
0
|
1
|
0
|
0
|
2
|
2
|
Суп
|
0
|
1
|
2
|
1
|
0
|
0
|
0
|
0
|
В отличие от сводных таблиц, в операторе PIVOT требуется явно перечислить столбцы для вывода. Это серьезное ограничение, т.к. для этого нужно знать характер данных, а значит, и применять в приложениях этот оператор мы сможем, как правило, только к справочникам (вернее, к данным, которые берутся из справочников).
Синтаксис:
SELECT <несведенный столбец>,
[первый сведенный столбец] AS <имя столбца>,
[второй сведенный столбец] AS <имя столбца>,
...
[последний сведенный столбец] AS <имя столбца>,
FROM
(< запрос SELECT, извлекающий эти данные>)
AS <псевдоним исходного запроса>
PIVOT
(
<статистическая функция>(<статистически обработанный столбец>)
FOR
[<столбец, содержащий значения, которые станут именами столбцов>]
IN ( [первый сведенный столбец], [второй сведенный столбец],
... [последний сведенный столбец])
)AS <псевдоним сведенной таблицы>
<необязательное предложение ORDER BY>;
Приведенную таблицу можно заполнить и стандартным способом с использованием оператора CASE:
SELECT s.Вид,
SUM(CASE Основа WHEN 'Овощи' THEN 1 ELSE 0 END) Овощи
, SUM(CASE Основа WHEN 'Мясо' THEN 1 ELSE 0 END) Мясо
, SUM(CASE Основа WHEN 'Рыба' THEN 1 ELSE 0 END) Рыба
,SUM(CASE Основа WHEN 'Молоко' THEN 1 ELSE 0 END) Молоко ,SUM(CASE Основа WHEN 'Яйца' THEN 1 ELSE 0 END) Яйца
,SUM(CASE Основа WHEN 'Крупа' THEN 1 ELSE 0 END) Крупа
,SUM(CASE Основа WHEN 'Фрукты' THEN 1 ELSE 0 END) Фрукты ,SUM(CASE Основа WHEN 'Кофе' THEN 1 ELSE 0 END) Кофе
FROM Блюда b JOIN Справочник_вид_блюда s ON b. Вид = s.ID_ Вид
GROUP BY s. Вид;
Где опреатор Case имеет следующий синтаксис:
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
input_expression —представляет собой любое допустимое выражение.
WHEN when_expression — простое выражение, с которым сравнивается аргумент input_expression. Типы данных аргумента input_expression и каждого из выражений when_expression должны быть одинаковыми или неявно приводимыми друг к другу.
THEN result_expression — выражение, возвращаемое, если сравнение выражений input_expression и when_expression дает в результате TRUE или выражение Аргумент result expression представляет собой любое допустимое выражение.
ELSE else_result_expression —выражение, возвращаемое, если ни одна из операций сравнения не дает в результате TRUE. Если этот аргумент опущен и ни одна из операций сравнения не дает в результате TRUE, функция CASE возвращает NULL. Аргумент else_result_expression представляет собой любое допустимое выражение. Типы данных аргумента else_result_expression и любого из аргументов result_expression должны быть одинаковыми или неявно приводимыми друг к другу.
Как следует из названия оператора, UNPIVOT выполняет обратную по отношению к PIVOT операцию, т.е. представляет данные, записанные в строке таблицы, в одном столбце.
Пусть мы получили следующий результат, ограничив вывод Вид = ‘Горячее’
Вид
|
Овощи
|
Мясо
|
Рыба
|
Молоко
|
Яйца
|
Крупа
|
Фрукты
|
Кофе
|
Горячее
|
2
|
2
|
1
|
3
|
2
|
2
|
0
|
0
|
Развернуть эту таблицу в столбец мы можем следующим запросом
SELECT Основа,
-- заголовок столбца, который будет содержать заголовки строк исходной таблицы
Горячее
-- заголовок столбца, который будет содержать значения из строки исходной таблицы
From ( SELECT Вид, [Овощи], [Мясо], [Рыба]
, [Молоко], [Яйца], [Крупа], [Фрукты], [Кофе]
FROM ( -- pivot-запрос из предыдущего примера
SELECT s.Вид, Основа
FROM Блюда b JOIN Справочник_вид_блюда s
ON b.Вид = s.ID_Вид) a
PIVOT
(COUNT(Основа)
FOR Основа
IN ([Овощи], [Мясо], [Рыба], [Молоко], [Яйца], [Крупа], [Фрукты], [Кофе])
) pvt -- конец pivot-запроса
) pvt1
UNPIVOT
(Горячее
-- заголовок столбца, который будет содержать значения из столбцов исходной таблицы, перечисленных ниже
FOR Основа
IN ([Овощи], [Мясо], [Рыба], [Молоко], [Яйца], [Крупа], [Фрукты], [Кофе])
)unpvt;
Результат
|
|
Основа
|
Горячее
|
Овощи
|
2
|
Мясо
|
2
|
Рыба
|
1
|
Молоко
|
3
|
Яйца
|
2
|
Крупа
|
2
|
Фрукты
|
0
|
Кофе
|
0
|
Глава 7. Операторы манипулирования данными.
Операторы манипулирования данными (DML – Data Manipulation Language) предназначены для изменения данных в существующих таблицах БД. В этот раздел языка SQL входят три оператора:
INSERT – добавление новых данных,
DELETE – удаление данных и
UPDATE – изменение существующих данных.
Все операторы манипулирования данными позволяют изменить данные только в одной таблице.
7.1. Оператор INSERT для добавления одной записи.
Синтаксис:
INSERT INTO <имя_таблицы> [(<список столбцов>) ]
VALUES (<список значений>)
Задание списка столбцов необязательно тогда, когда мы вводим строку с указанием значений всех столбцов.
Пример 46.
Добавим новое блюдо в таблицу Блюда
INSERT INTO Блюда (ID_Блюда, Блюдо, Вид, Основа, Вес, Труд)
VALUES (34, 'Шашлык', 3, 'Мясо', 150 , 4);
Так как мы заполняем все поля, и данные передаем в соответствии со списком полей таблицы, то мы можем не задавать список столбцов, ограничиться только заданием перечня значений, в этом случае оператор ввода будет выглядеть следующим образом:
INSERT INTO Блюда
VALUES (34, 'Шашлык', 3, 'Мясо', 150, 4);
Результаты работы обоих операторов одинаковые.
Какие столбцы должны быть заданы при вводе данных? Это определяется тем, как описаны эти столбцы при создании соответствующей таблицы. Если столбец имеет признак обязательный (NOT NULL) при создании таблицы, то оператор INSERT должен обязательно содержать данные для ввода в каждую строку данного столбца. Поэтому если в таблице все столбцы обязательные, то каждая вводимая строка должна содержать полный перечень вводимых значений, а указание имен столбцов в этом случае необязательно. Если имеется хотя бы один необязательный столбец, и вы не вводите в него значение, задание списка имен столбцов — обязательно.
INSERT INTO Продукты (ID_Продукта, Продукт, Белки)
VALUES (18, 'Горох', 180 );
Все остальные столбцы таблицы Продукты получат значение NULL или значение по умолчанию, которое было задано при создании таблицы.
Многие коммерческие продукты допускают использование автоинкрементируемых столбцов в таблицах, то есть столбцов, значение которых формируется автоматически при добавлении новых записей. Такие столбцы широко используются в качестве первичных ключей таблицы, так как они автоматически обеспечивают уникальность за счет того, что генерируемые значения не повторяются. Типичным примером столбца такого типа является последовательный счетчик, который при вставке строки генерирует значение на единицу большее предыдущего значения (значения, полученного при вставке предыдущей строки). При вставке значения в поле такого типа произойдет ошибка. Поэтому в этом случае поступают аналогично значениям по умолчанию – формируют список полей для ввода, в котором автоинкрементное поле не указывается.
Вставка NULL-значений может выполнятся командой:
INSERT INTO Продукты (Продукт, Белки, Жиры)
VALUES ( 'Горох', 180, NULL);
Так как значение NULL - это специальный маркер, а не просто символьное значение, он не включается в одиночные кавычки. Поле ID_Продукта в данном случае не указывается, так как оно автоинкрементное.
7.2. Оператор INSERT для добавления набора записей.
Синтаксис:
INSERT INTO <имя_таблицы> [(<список столбцов>)]
SELECT …
Оператор ввода данных позволяет ввести сразу множество строк, если их можно выбрать из некоторой другой таблицы.
Допустим, мы хотим в меню на ‘03-01-2011’ добавить все горячие блюда из ассортимента ресторана.
Пример 47.
INSERT INTO Меню
SELECT b. ID_Блюда, b.Вид, '2011-01-03'
Do'stlaringiz bilan baham: |