Шпаргалка по оконным функциям SQL. Часть #1

SQL (Structured Query Language) — это язык для работы с базами данных. Позволяет выбирать данные и строить сложные отчеты. Сегодня SQL стал универсальным языком данных.

Оконные функции

Оконные функции вычисляют свои результаты на основе скользящего окна — набора строк, которые так или иначе связаны с текущей строкой.


Агрегатные и оконные функции

В отличие от агрегирующих функций, оконные функции не объединяют строки.


Синтаксис

SELECT <column_1>, 
       <column_2>,
       <window_function> OVER (PARTITION BY <...>
                               ORDER BY <...>
                               <window_frame>) <window_column_alias>
  FROM <table_name>;
SELECT city, 
       month,
       SUM(sold) OVER (PARTITION BY city 
                       ORDER BY month 
                       RANGE UNBOUNDED PRECEDING) AS total
  FROM sales;

Определение именованного окна

  SELECT <column_1>, 
         <column_2>,
         <window_function>() OVER <window_name>
    FROM <table_name>
   WHERE <...>
GROUP BY <...>
  HAVING <...>
  WINDOW <window_name> AS (
     PARTITION BY <...>
     ORDER BY <...>
     <window_frame>)
ORDER BY <...>;
  SELECT country,
         city, 
         RANK() OVER country_sold_avg
    FROM sales
   WHERE month BETWEEN 1 AND 6
GROUP BY country, city
  HAVING sum(sold) > 10000
  WINDOW country_sold_avg AS (
     PARTITION BY country 
     ORDER BY avg(sold) DESC) 
ORDER BY country, city;

Оператор PARTITION BY

Оператор PARTITION BY разделяет строки на несколько групп, называемых партициями (разделами), к которым применяется оконная функция

Партиция по умолчанию: Если предложение PARTITION BY не указано, то вся результирующая выборка считается одной партицией.

Результат данных справа — применение оператора PARTITION BY city

monthcitysold
1Рим200
2Париж500
1Москва100
1Париж300
2Рим300
2Москва400
3Рим400
monthcitysoldsum
1Париж300800
2Париж500800
1Рим200900
2Рим300900
3Рим400900
1Москва100500
2Москва400500

Оператор ORDER BY

Оператор ORDER BY определяет порядок строк в каждой партиции, к которой применяется оконная функция

Сортировка по умолчанию: Если предложение ORDER BY не указано, порядок строк в каждой партиции является произвольным.

Результат данных справа — применение операторов PARTITION BY city ORDER BY month

monthcitysold
1Рим200
2Париж500
1Москва100
1Париж300
2Рим300
2Москва400
3Рим400
monthcitysold
1Париж300
2Париж500
1Рим200
2Рим300
3Рим400
1Москва100
2Москва400

Границы окна (window frame)

Границы окна определяют набор строк, связанных с текущей строкой. Для каждой партиции границы окна вычисляются отдельно.

Границы окна по умолчанию: если оператор ORDER BY определен, тогда окно использует поведение RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. Без указания ORDER BY используется поведение ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

< ROWS | RANGE | GROUPS > BETWEEN нижняя_граница AND верхняя_граница

Границы окна могут быть заданы одним из пяти способов

  • UNBOUNDED PRECEDING или BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  • n PRECEDING или BETWEEN n PRECEDING AND CURRENT ROW
  • CURRENT ROW или BETWEEN CURRENT ROW AND CURRENT ROW
  • n FOLLOWING или BETWEEN CURRENT ROW AND n FOLLOWING
  • UNBOUNDED FOLLOWING или BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING

Пример ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING

1 строка до текущей строки (current row) и 1 строка после текущей строки (current row)

Пример RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING

Значения в диапазоне (range) от 3 до 5 и оператор ORDER BY должен содержать единственное выражение

Пример GROUPS BETWEEN 1 PRECEDING AND 1 FOLLOWING

1 группа строк (group) до текущей строки (current row) и 1 группа строк (group) после текущей строки (current row), независимо от значения