SQL имеет несколько возможностей для поддержки OLAP. С агрегирующими операторами вы уже знакомы. SQL для OLAP поддерживает механизмы многоуровневой агрегации. Предположим, нужно вывести среднюю зарплату по городам и среднюю зарплату по городам и отделам в одном запросе. Для этого, используя традиционный SQL, нужно написать два запроса и объединить их с помощью UNION (запрос приведен на Лист. 44, результат - Табл. 56).
Лист. 44. Запрос на многоуровневую агрегацию
SELECT Город, 'по всем отделам' AS Отдел, avg(Зарплата) AS Средняя_Зарплата
FROM Продавцы
GROUP BY Город
UNION SELECT Город, Отдел, avg(Зарплата) AS Средняя_Зарплата
FROM Продавцы
GROUP BY Город, Отдел;
Табл. 56. Результат запроса на многоуровневую агрегацию
36 Многоуровневая агрегация
Город
Отдел
Средняя_Зарплата
Екатеринбург
опт
Екатеринбург
по всем отделам
Екатеринбург
розница
Москва
опт
Москва
по всем отделам
33333,3333333333
Москва
розница
Используя механизмы OLAP, данный запрос можно написать значительно короче (см. Лист. 45).
Лист. 45. Запрос OLAP на многоуровневую агрегацию
SELECT Город, Отдел, MAX (Зарплата)
FROM Продавцы
GROUP BY ROLLUP (Город, Отдел);
Иногда бывают ситуации, когда поля не обязательны для заполнения. В этом случае при выполнении предыдущего запроса возникает проблема, что могут быть продавцы из какого-нибудь города, у которых не указан отдел. Нужно различать среднюю стоимость по продавцам без отдела и среднюю стоимость по городу. Для этого вводится дополнительная колонка с помощью оператора GROUPING, которая содержит ”1”, если имеется в виду средняя стоимость по городу, и ”0”, если средняя стоимость по продавцам без отдела (см. Лист. 46)
Лист. 46. Уточненный запрос OLAP на многоуровневую агрегацию
SELECT Город, Отдел, MAX (Зарплата), GROUPING(Город), GROUPING(Отдел)
FROM Продавцы
GROUP BY ROLLUP (Город, Отдел);
Предположим, нам нужно произвести многоуровневую агрегацию по альтернативным иерархиям, например, вывести среднюю зарплату по городам, среднюю зарплату по отделам и среднюю зарплату по городам и отделам в одном запросе. Запрос на традиционном SQL приведен на Лист. 47, результаты – в Табл. 57, запрос на SQL с использованием OLAP – Лист. 48).
Лист. 47. Запрос на многоуровневую агрегацию по всем измерениям
SELECT Город, 'по всем отделам' AS Отдел, avg(Зарплата) AS Средняя_Зарплата
FROM Продавцы
GROUP BY Город
UNION SELECT 'по всем городам' AS Город, Отдел, avg(Зарплата) AS Средняя_Зарплата
FROM Продавцы
GROUP BY Отдел
UNION SELECT Город, Отдел, avg(Зарплата) AS Средняя_Зарплата
FROM Продавцы
GROUP BY Город, Отдел;
Табл. 57. Результат запроса на многоуровневую агрегацию по всем измерениям
37 Многоуровневая агрегация по всем измерениям
Город
Отдел
Средняя_Зарплата
Екатеринбург
опт
Екатеринбург
по всем отделам
Екатеринбург
розница
Москва
опт
Москва
по всем отделам
33333,3333333333
Москва
розница
по всем городам
опт
по всем городам
розница
23333,3333333333
Лист. 48 Запрос OLAP на многоуровневую агрегацию по всем измерениям
SELECT Город, Отдел, MAX (Зарплата), GROUPING(Город), GROUPING(Отдел)
FROM Продавцы
GROUP BY ROLLUP CUBE(Город, Отдел);
В OLAP помимо avg, min, max, count и sum предусмотрены дополнительные статистические функции, приведенные в Табл. 58.
Табл. 58. Статистические функции OLAP
Функция
Описание
Rank(x) - ранг
Записи сортируются по полю x, каждой записи присваивается номер по порядку. Если записи имеют одинаковый x, то им присваивается одинаковый номер, ранг следующей записи за группой записей c одинаковым рангом больше ранга этой группы на количество записей в группе. Например, последовательность рангов: (1 2 3 3 5 6 7 7 7 10)
Densrank(x) - Конденсированный ранг
В отличие от ранга нет пропусков между порядками: (1 2 3 3 4 5 6 6 6 7)
Ntile(x)
Ранг, деленный на x.
Percentrank(x)
Ранг, нормированный от 0 до 1.
Cumedist(x) – накапливающееся распределение
Количество предыдущих строк + 1, деленное на общее число строк
Rownumber
Номер строки
Ratiotoreport(x)
Отношение значения атрибута к сумме значений этого атрибута по всей колонке.
Предположим, для каждого продавца нужно посчитать скользящее среднее стоимости по трем датам. То есть для каждой даты нужно посчитать среднюю стоимость продаж за эту дату и три предыдущих дня. Традиционными средствами SQL написать такой запрос не просто. В OLAP есть аналитические запросы с окном. Пример запроса приведен на Лист. 49. В нем после статистической функции avg в круглых скобках описывается окно. PARTITION BY задает разбиение таблицы на группы по продавцам, а ROWS 2 PRECEDING – размер окна.
Лист. 49. Аналитический запрос с окном
SELECT Дата, N_Продавца,
AVG (Стоимость)
OVER (PARTITION BY N_Продавца
ORDER BY Дата ASC
ROWS 2 PRECEDING )
AS ‘Скользящее среднее’
FROM Сделки
ORDER BY Дата ASC;
Подробнее об аналитических запросах см. [4].
Д/З 8. Для БД из Д/З 4 напишите следующие запросы:
Аналитический запрос c group by rollup cube.
Аналитический запрос с окном.
Вопросы для самопроверки:
Чем отличается использование операторов group by, group by rollup, group by rollup cube, grouping, orger by, partition?