Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки? Спасибо! |
SQL в хранилищах данных: аналитическая обработка данных
Функция ROW_NUMBER
Функция ROW_NUMBER() назначает уникальный номер (последовательно, начиная с 1, в порядке, определенном ORDER BY ) каждой строке в секции.
Синтаксис:
ROW_NUMBER ( ) OVER ( [ <partition_by_clause> ] <order_by_clause> )
<partition_by_clause> делит результирующий набор, полученный по предложению FROM.
<order_by_clause> определяет порядок, в котором значение функции ROW_NUMBER назначается строкам в секции. Целое число не может представлять столбец, если аргумент <order_by_clause> используется в ранжирующей функции.
Предложение ORDER BY определяет последовательность, в которой строкам назначаются уникальные номера с помощью функции ROW_NUMBER в пределах указанной секции.
Пример 23.8. Использование функции ROW_NUMBER ()
Пусть нам нужно провести группировку проданных товаров по объему продаж, используя схему на рис. 23.5. Это можно сделать с помощью следующего запроса:
SELECT p_productkey, s_amount, ROW_NUMBER() (ORDER BY s_amount DESC) AS srnum FROM product, sales WHERE product.p_productkey = sales.p_productkey;
Результат выполнения запроса приведен ниже.
Вывод 8.
P_PRODUCTKEY | S_AMOUNT | SRNUM |
---|---|---|
Ботинки | 100 | 1 |
Жакеты | 90 | 2 |
Рубашки | 89 | 3 |
Футболки | 84 | 4 |
Свитеры | 75 | 5 |
Джинсы | 75 | 6 |
Ремни | 75 | 7 |
Брюки | 69 | 8 |
Ленты | 56 | 9 |
Носки | 45 | 10 |
Костюмы | NULL | 11 |
Свитерам, джинсам и ремням (с s_amount = 75) назначаются различные номера строк (5, 6, 7).
Подобно функции NTILE(), функция ROW_NUMBER() является недетерминистической функцией, так что "свитеры" мог бы получить номер строки 7 (вместо 5), а "ремни" — 5 (вместо 7). Чтобы избежать подобных ситуаций, необходимо сортировать результирующее множество по уникальному ключу.
Функции, генерирующие отчеты
После того как запрос выполнен, значения агрегатов (типа количество строк в результирующем множестве или среднее значение в колонке) могут быть вычислены для секции и быть доступными для других отчетов. Агрегатные функции генерирования отчетов (Reporting aggregate functions) возвращают значения агрегатов для каждой строки в секции. К агрегатным функциям генерирования отчетов относятся функции SUM(), AVG(), MAX(), MIN(), COUNT(), использующее предложение OVER. Их поведение относительно NULL-значений такое же, как и в агрегатных функциях SQL.
В предыдущих разделах настоящей лекции мы уже обсуждали такое применение агрегатных функций. Поэтому в настоящем разделе приведем только несколько примеров.
Функции генерирования отчетов допустимы только для предложений SELECT. Основное их назначение состоит в способности выполнять многократный разбор блока данных результирующего множества запроса. Запросы типа "Подсчитать число продавцов, у которых уровень продаж больше на 10% от числа продаж по городу" не требуют соединений между отдельными блоками запроса.
Пример 23.9. Использование агрегатных функций для генерирования отчетов
Пусть нам нужно для каждого товара найти регион, в котором наблюдается максимальный уровень продаж каждого товара, используя схему на рис. 23.5. Это можно сделать с помощью следующего запроса:
SELECT s_productkey, s_regionkey, sum_s_amount FROM (SELECT p_productkey, r_regionkey, SUM(s_amount) AS 'sum_s_amount', MAX(SUM(s_amount)) OVER (PARTITION BY p_productkey) AS 'max_sum_s_amount' FROM sales GROUP BY p_productkey, r_regionkey) WHERE sum_s_amount = max_sum_s_amount;
Данные внутреннего запроса к таблице фактов "Продажи" (sales), сгруппированные по колонкам p_productkey и p_regionkey, агрегируются для первых трех колонок, и функция MAX(SUM(s_amount)) возвращает результат.
Вывод 9.
P_PRODUCTKEY | S_REGIONKEY | SUM_S_AMOUNT | MAX_SUM_S_AMOUNT |
---|---|---|---|
Жакеты | Запад | 99 | 99 |
Жакеты | Восток | 50 | 99 |
Брюки | Восток | 20 | 45 |
Брюки | Запад | 45 | 45 |
Рубашки | Восток | 60 | 80 |
Рубашки | Запад | 80 | 80 |
Ботинки | Запад | 100 | 130 |
Ботинки | Восток | 130 | 130 |
Свитеры | Запад | 75 | 75 |
Свитеры | Восток | 75 | 75 |
Носки | Восток | 95 | 95 |
Носки | Запад | 66 | 95 |
Результат выполнения внешнего запроса приведен ниже.
Вывод 10.
P_PRODUCTKEY | S_REGIONKEY | SUM_S_AMOUNT |
---|---|---|
Жакеты | Запад | 99 |
Брюки | Запад | 45 |
Рубашки | Запад | 80 |
Ботинки | Восток | 130 |
Свитеры | Запад | 75 |
Свитеры | Восток | 75 |
Носки | Восток | 95 |
Пример 23.10. Использование агрегирующих и ранжирующих функций для генерации отчета.
Более сложным является пример вычисления первых 10-ти (top 10) продаж той линейки товаров, которая имеет вклад более 10% в продажи товаров этой категории. Физическая схема для таблиц, используемых для решения этой задачи, приведена на рис. 23.6. Первая колонка является ключом для всех таблиц запроса.
SELECT * FROM ( SELECT item_name, prod_line_name, prod_cat_name, SUM(sales) OVER (PARTITION BY prod_cat_table.cat_id) cat_sales, SUM(sales) OVER (PARTITION BY prod_line_table.line_id) line_sales, RANK(sales) OVER (PARTITION BY prod_line_table.line_id ORDER BY sales DESC) rnk FROM item_table, prod_line_table, prod_cat_table WHERE item_table.line_id = prod_line_table.line_id AND prod_line_table.cat_id = prod_cat_table.cat_id ) WHERE line_sales > 0.1 * cat_sales AND rnk <= 10;