SQL: нумерация строк, возвращаемых оператором SELECT - PullRequest
4 голосов
/ 12 ноября 2008

Предположим, у меня есть оператор SELECT, который возвращает некоторый набор результатов. Можно ли как-нибудь подсчитать свои результаты следующим образом:

ВЫБРАТЬ ТОП 3 имени из PuppyNames ЗАКАЗАТЬ ПО NumberOfVotes

дал бы мне ...

Fido

Rover

Фредди Крюгер

... но я хочу ...

1, Фидо

2, Ровер

3, Фредди Крюгер

где, конечно, запятые означают, что числа находятся в своем собственном столбце. [Я использую SQL Server 2000.]

Ответы [ 6 ]

5 голосов
/ 12 ноября 2008

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

Если вы застряли на SQL Server 2000, типичным методом было создание новой временной таблицы, содержащей результат вашего запроса, плюс добавление столбца IDENTITY и генерирование дополнительных значений. Смотрите статью, в которой рассказывается об этой технике здесь: http://www.databasejournal.com/features/mssql/article.php/3572301/RowNumber-function-in-SQL-Server-2005.htm

3 голосов
/ 12 ноября 2008

В SQL 2000 вам нужно использовать коррелированный подзапрос.

   SELECT (
              SELECT COUNT(*)
                FROM PuppyNames b
               WHERE b.Popularity <= a.Popularity
          ) AS Ranking
        , a.Name
     FROM PuppyNames a
 ORDER BY a.Popularity
2 голосов
/ 12 ноября 2008

Вы также можете сделать это с временной таблицей:

SELECT TOP 3 Name FROM PuppyNames ORDER BY NumberOfVotes DESC

становится

CREATE TABLE #RowNumberTable (
    RowNumber int IDENTITY (1,1),
    PuppyName varchar(MAX)
)
INSERT #RowNumberTable (PuppyName)
SELECT TOP 3 Name FROM PuppyNames ORDER BY NumberOfVotes DESC
SELECT * from #RowNumberTable ORDER BY RowNumber
DROP TABLE #RowNumberTable

Если вы заметите, ваше утверждение SELECT там. Он просто окружен вещами, которые заставляют работать номера строк.

2 голосов
/ 12 ноября 2008

Обычно проще добавить числа в клиентское приложение. В SQL есть хитрости, но для пуриста они связаны с мошенничеством, и они обычно не переносимы.

Для меня это один из самых базовых шаблонов рефакторинга.

1 голос
/ 12 ноября 2008

Вы можете использовать этот запрос, который учитывает PK, чтобы обеспечить правильную нумерацию в случае того же NumberOfVotes:

SELECT TOP 3 COUNT(*) AS Number, p1.Name
FROM PuppyNames AS p1 INNER JOIN PuppyNames AS p2 
    ON p1.NumberOfVotes < p2.NumberOfVotes OR (p1.NumberOfVotes = p2.NumberOfVotes AND p1.ID >= p2.ID)
GROUP BY p1.Name
ORDER BY Number
0 голосов
/ 12 ноября 2008

SQL 2005, 2008:

ВЫБРАТЬ ТОП 3 ROW_NUMBER () OVER (ORDER BY NumberOfVotes DESC) AS VoteRank, Имя ИЗ PuppyNames

РЕДАКТИРОВАТЬ: Извините - только что вы указали 2000.

...