Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка SQL(14) (оптимизация).docx
Скачиваний:
62
Добавлен:
17.03.2015
Размер:
452.16 Кб
Скачать

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 Основа