Получение номера строки

Оконные функции возвращают одно значение по всем строкам или по группе строк.

Оконные функции очень похожи на агрегатные функции, только они не изменяют итоговое количество строк, а вычисляют результат для каждой строки.

Важно знать момент вычисления оконных функций в выполнении запроса. Они вычисляются после соединения таблиц во FROM, отсечения строк в WHERE и группировки GROUP BY и HAVING, но перед сортировкой результата запроса через ORDER BY. Поэтому оконные функции можно использовать в списке выборки (сразу после SELECT) и ORDER BY.

SELECT можно_здесь
    FROM ...
 WHERE ...
 GROUP BY ...
HAVING ...
 ORDER BY и_здесь 

Вычисление максимального значения

Наглядно продемонстрируем различие агрегатных и оконных функций. Определим максимальную цену на товар из таблицы product_price.

Агрегатная функция:

SELECT max(pp.price) AS max_price
  FROM product_price pp
# max_price
1 1321800000.00

Оконная функция:

SELECT pp.*,
       max(pp.price) OVER () AS max_price
  FROM product_price pp
# product_id store_id price max_price
1 1 300 10500.00 1321800000.00
2 10 400 75600.00 1321800000.00
3 8 400 37000.00 1321800000.00
... ... ... ... ...

При использовании агрегатной функции получили одну единственную строку с максимальным значением. При использовании оконной функции получили столько же строк, сколько в таблице product_price.

Обрати внимание, что при использовании оконных функций в списке выборки доступны все поля из таблицы. При использовании агрегатных функций доступны только поля, перечисленные в GROUP BY.

Синтаксис

Общий синтаксис вызова оконных функций:

функция(...) OVER (условия для группировки строк и сортировки)

Оконную функцию можно отличить от агрегатной по ключевому слову OVER.

Определение номера строки

Для определение номера строки воспользуемся оконной функцией row_number()

SELECT row_number() OVER (ORDER BY c.name) as row_num,
       c.name
  FROM category c
# row_num name
1 1 Аудиотехника
2 2 Бытовая техника
3 3 Игровые консоли
4 4 Ноутбуки
5 5 Ноутбуки и аксессуары
6 6 Рюкзаки
7 7 Сотовые телефоны
8 8 Товары для дома
9 9 Фотоаппараты
10 10 Цифровая техника

row_number - оконная функция, которая возвращает номер строки в порядке, указанном в ORDER BY внутри OVER.

ORDER BY внутри OVER не связан с сортировкой строк в результате запроса. Результат запроса нужно сортировать явно через ORDER BY. То, что в результате мы получили отсортированные в алфавитном порядке строки, можно считать случайностью (конечно, они не случайно в таком порядке вернулись, но порядок может измениться в любой момент).

Отсортируем результат:

SELECT row_number() OVER (ORDER BY c.name) as row_num,
       c.name
  FROM category c
 ORDER BY row_num
# row_num name
1 1 Аудиотехника
2 2 Бытовая техника
3 3 Игровые консоли
4 4 Ноутбуки
5 5 Ноутбуки и аксессуары
6 6 Рюкзаки
7 7 Сотовые телефоны
8 8 Товары для дома
9 9 Фотоаппараты
10 10 Цифровая техника

А можно отсортировать в другом порядке:

SELECT row_number() OVER (ORDER BY c.name) as row_num,
       c.name
  FROM category c
 ORDER BY c.name DESC
# row_num name
1 10 Цифровая техника
2 9 Фотоаппараты
3 8 Товары для дома
4 7 Сотовые телефоны
5 6 Рюкзаки
6 5 Ноутбуки и аксессуары
7 4 Ноутбуки
8 3 Игровые консоли
9 2 Бытовая техника
10 1 Аудиотехника

10.12 Листовые строки CONNECT_BY_ISLEAF

11.2 Номер строки в рамках группы