Давай научимся нумеровать товары в рамках категории. Примерно так:
| # | category_name | position | product_name |
|---|---|---|---|
| 1 | Бытовая техника | 1 | Пылесос S6 |
| 2 | Бытовая техника | 2 | Холодильник A2 |
| 3 | Игровые консоли | 1 | Nintendo |
| 4 | Игровые консоли | 2 | PlayStation |
| 5 | Игровые консоли | 3 | Xbox |
| ... | ... | ... | ... |
Мы умеем делать сквозную нумерацию через row_number(). Чтобы сделать отдельную нумерацию в рамках категории, достаточно в OVER добавить разбивку по категориям через PARTITION BY:
SELECT c.category_id,
c.name AS category_name,
row_number () OVER (PARTITION BY c.category_id ORDER BY p.name) AS position,
p.name AS product_name
FROM category c,
product p
WHERE p.category_id = c.category_id
ORDER BY c.name, position
| # | category_id | category_name | position | product_name |
|---|---|---|---|---|
| 1 | 7 | Аудиотехника | 1 | Наушники S3 |
| 2 | 3 | Бытовая техника | 1 | Пылесос S6 |
| 3 | 3 | Бытовая техника | 2 | Холодильник A2 |
| 4 | 6 | Игровые консоли | 1 | Nintendo |
| 5 | 6 | Игровые консоли | 2 | PlayStation |
| 6 | 6 | Игровые консоли | 3 | Xbox |
| 7 | 9 | Ноутбуки | 1 | Ультрабук X5 |
| 8 | 10 | Рюкзаки | 1 | Deepbox |
| 9 | 8 | Сотовые телефоны | 1 | Моноблок C4 |
| 10 | 8 | Сотовые телефоны | 2 | Слайдер B3 |
| 11 | 5 | Фотоаппараты | 1 | Lord Nikon 95 |
| 12 | 5 | Фотоаппараты | 2 | Nikon D750 |
Как работает PARTITION BY
PARTITION BY работает в оконных функциях так же, как и GROUP BY в агрегатных.
Для вычисления оконной функции все строки запроса разбиваются на группы с одинаковыми значениями полей, перечисленных после PARTITION BY.
У нас PARTITION BY c.category_id, следовательно row_number() вычисляется независимо для следующих наборов строк:
| # | category_id | category_name | product_name |
|---|---|---|---|
| 1 | 7 | Аудиотехника | Наушники S3 |
| # | category_id | category_name | product_name |
|---|---|---|---|
| 2 | 3 | Бытовая техника | Пылесос S6 |
| 3 | 3 | Бытовая техника | Холодильник A2 |
| # | category_id | category_name | product_name |
|---|---|---|---|
| 4 | 6 | Игровые консоли | Nintendo |
| 5 | 6 | Игровые консоли | PlayStation |
| 6 | 6 | Игровые консоли | Xbox |
| # | category_id | category_name | product_name |
|---|---|---|---|
| 7 | 9 | Ноутбуки | Ультрабук X5 |
| # | category_id | category_name | product_name |
|---|---|---|---|
| 8 | 10 | Рюкзаки | Deepbox |
| # | category_id | category_name | product_name |
|---|---|---|---|
| 9 | 8 | Сотовые телефоны | Моноблок C4 |
| 10 | 8 | Сотовые телефоны | Слайдер B3 |
| # | category_id | category_name | product_name |
|---|---|---|---|
| 11 | 5 | Фотоаппараты | Lord Nikon 95 |
| 12 | 5 | Фотоаппараты | Nikon D750 |
Затем в каждой группе строки сортируются по p.name и получают свой порядковый номер функцией row_number().