Порядковые номера строк в запросах PostgreSQL 8.4
Быстрый ответ
Чтобы прикрепить порядковые номера к результатам запроса в PostgreSQL, можно использовать функцию ROW_NUMBER()
, применяв ее вместе с предложением OVER()
. Если требуется упорядочить результаты в конкретном порядке, добавьте ORDER BY
в OVER()
.
В качестве образца запроса рассмотрим:
SELECT
ROW_NUMBER() OVER (ORDER BY column_to_sort) AS row_number,
other_columns
FROM
table_name;
Вам следует заменить column_to_sort
, other_columns
и table_name
на соответствующие названия столбцов и таблицы. В результате вы получите дополнительный столбец row_number
, пронумерованный в заданном порядке.
Если не обязательно поддерживать порядок, и требуется только присвоить номера строк без сортировки, просто пропустите ORDER BY
:
SELECT
ROW_NUMBER() OVER () AS row_number,
*
FROM
table_name;
Такой запрос добавит столбец с номером строки row_number
к неупорядоченному результату.
Работа с особыми сценариями
Справляемся с NULL значением
Если требуется расположить строки с NULL в столбце для сортировки в конце списка, примените NULLS LAST
:
SELECT
ROW_NUMBER() OVER (ORDER BY column_to_sort NULLS LAST) AS row_number,
*
FROM
table_name;
Это поместит строки с NULL в конец результатов.
Увеличиваем производительность при работе с большим объёмом данных
Функция ROW_NUMBER()
может уменьшать производительность, особенно при работе с большими наборами данных, так что не забудьте об корректной индексации столбца сортировки. Иногда может быть более продуктивным назначать номера строк на уровне приложения.
Сохраняем совместимость со старыми версиями PostgreSQL
В PostgreSQL до версии 8.4 функция ROW_NUMBER()
отсутствовала, но можно эмулировать ее действие с использованием самосоединения (self-join):
SELECT
COUNT(t1.id) AS row_number,
t2.*
FROM
table_name t1
JOIN
table_name t2 ON t1.id <= t2.id
GROUP BY
t2.id
ORDER BY
row_number;
Здесь вместо id
подставьте имя столбца, который представляет собой первичный ключ.
Визуализация
В задаче найти определенное место на концерте представление выглядит следующим образом:
Номер места | Ряд 1 | Ряд 2 | Ряд 3 |
---|---|---|---|
1 | 🤩 | ||
2 | 🤩 | 🎶 | |
3 | 🤩 | 🎶 | 🎸 |
Каждому месту соответствует номер строки в результате запроса:
SELECT ROW_NUMBER() OVER (), * FROM concerts;
Таким образом, ROW_NUMBER()
сохраняет порядок строк, аналогично порядку мест на концерте.
Обработка ситуаций, когда отсутствуют первичные ключи
Если в таблице отсутствуют первичные ключи, вы можете применить array_agg
, однако стоит быть готовым к возможному снижению производительности.
WITH numbered_rows AS (
SELECT array_agg(t.*) AS rows
FROM your_table t
)
SELECT
row_number() OVER (),
r.*
FROM
numbered_rows,
LATERAL unnest(rows) as r;
Решаем особо сложные запросы
При составлении запросов с использованием сложных оконных функций оказывается полезным применение подзапросов или CTE:
WITH numbered AS (
SELECT
*,
ROW_NUMBER() OVER (ORDER BY your_sort_column) AS row_number
FROM
your_table
)
SELECT * FROM numbered;
Обмен информацией через SQL Fiddle
Платформа SQL Fiddle будет полезна для отладки и обмена запросами. Создавайте схемы и проверяйте SQL-код в интерактивном режиме.
Полезные материалы
- Официальная документация PostgreSQL на тему оконных функций.
- Замечания и типичные проблемы при применении нумерации строк в PostgreSQL.
- Вводное руководство по использованию оконных функций для новичков в PostgreSQL.
- Глубокое исследование оконных функций для всестороннего понимания и эффективной их реализации.