Для начала, что-то вроде:
SELECT my_first_column, my_second_column,
ROW_NUMBER() OVER (ORDER BY my_order_column) AS Row_Counter
FROM my_table
Однако важно отметить, что конструкция ROW_NUMBER() OVER (ORDER BY ...)
определяет только значения Row_Counter
, это не гарантирует упорядочение результатов.
Если само SELECT
не имеет явного предложения ORDER BY
, результаты могут быть возвращены в любом порядке, в зависимости от того, как SQL Server решит оптимизировать запрос. ( См. Эту статью для получения дополнительной информации .)
Единственный способ гарантировать, что результаты будут всегда возвращаться в порядке Row_Counter
, состоит в том, чтобы применить одинаковый порядок к SELECT
и ROW_NUMBER()
:
SELECT my_first_column, my_second_column,
ROW_NUMBER() OVER (ORDER BY my_order_column) AS Row_Counter
FROM my_table
ORDER BY my_order_column -- exact copy of the ordering used for Row_Counter
Приведенный выше шаблон всегда будет возвращать результаты в правильном порядке и хорошо работает для простых запросов, но как насчет «произвольно сложного» запроса с, возможно, десятками выражений в предложении ORDER BY
? В этих ситуациях я предпочитаю что-то вроде этого:
SELECT t.*
FROM
(
SELECT my_first_column, my_second_column,
ROW_NUMBER() OVER (ORDER BY ...) AS Row_Counter -- complex ordering
FROM my_table
) AS t
ORDER BY t.Row_Counter
Использование вложенного запроса означает, что нет необходимости дублировать сложное предложение ORDER BY
, что означает меньше беспорядка и более простое обслуживание. Внешний ORDER BY t.Row_Counter
также делает цель запроса намного более понятной вашим коллегам-разработчикам.