SQLServer SQL-запрос со счетчиком строк - PullRequest
21 голосов
/ 29 января 2009

У меня есть SQL-запрос, который возвращает набор строк:

SELECT id, name FROM users where group = 2

Мне нужно также включить столбец, который имеет возрастающее целочисленное значение, поэтому первая строка должна иметь 1 в столбце счетчика, вторая - 2, третья - 3 и т. Д.

Показанный здесь запрос является лишь упрощенным примером, в действительности запрос может быть сколь угодно сложным, с несколькими объединениями и вложенными запросами.

Я знаю, что этого можно достичь с помощью временной таблицы с полем автонумерации, но есть ли способ сделать это в самом запросе?

Ответы [ 4 ]

26 голосов
/ 29 января 2009

Для начала, что-то вроде:

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 также делает цель запроса намного более понятной вашим коллегам-разработчикам.

10 голосов
/ 29 января 2009

В SQL Server 2005 и более поздних версиях вы можете использовать функцию ROW_NUMBER(), которая имеет параметры для порядка сортировки и групп, по которым подсчеты выполняются (и сбрасываются).

2 голосов
/ 20 декабря 2016

Самый простой способ - использовать переменный счетчик строк. Однако это будут две настоящие команды SQL. Один, чтобы установить переменную, а затем запрос следующим образом:

SET @n=0;
SELECT @n:=@n+1, a.* FROM tablename a

Ваш запрос может быть настолько сложным, насколько вам нравится с объединениями и т. Д. Я обычно делаю это хранимой процедурой. С переменной можно развлекаться всячески, даже использовать ее для вычисления значений полей. Ключ :=

0 голосов
/ 01 марта 2016

Вот другой подход. Если у вас есть несколько таблиц данных, которые не могут быть объединены, или по какой-то причине вы не хотите считать все строки одновременно, но все же хотите, чтобы они были частью одного и того же количества строк, вы можете создать таблицу, которая выполняет эту работу для тебя.

Пример:

create table #test (
        rowcounter int identity,
        invoicenumber varchar(30)
        )

insert into #test(invoicenumber) select [column] from [Table1]

insert into #test(invoicenumber) select [column] from [Table2]

insert into #test(invoicenumber) select [column] from [Table3]

select * from #test

drop table #test
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...