Hinzufügen einer automatisch generierten ID zum Aufzeichnen der Ergebnisse

Ich muss eine automatisch generierte Auto-Inkrement-ID zu einer Abfrageergebnisse hinzufügen. Zum Beispiel für die Abfrage

SELECT TOP 3 Users.Reputation FROM Users ORDER BY 1 DESC 

Anstatt zu bekommen

  • 101
  • 100
  • 99

ich möchte bekommen

  • 1, 101
  • 2, 100
  • 3, 99

Wie kann ich es tun?

Wie wäre es mit:

 ;WITH CTE AS (SELECT RowNum = ROW_NUMBER() OVER(ORDER BY Reputation DESC), Users.Reputation FROM Users ) SELECT TOP 3 RowNum, Reputation FROM CTE ORDER BY RowNum 

Dies ist ein CTE (Common Table Expression) in SQL server 2005 und neuer, kombiniert mit der ROW_NUMBER() Ranking-function, die auch im Jahr 2005 und neuer erhältlich ist.

Es schafft eine "on-the-fly" -view für nur die nächste statement und ermöglicht es, einige zusätzliche Verarbeitung zuerst, vor der Auswahl zu tun. Die ROW_NUMBER() fügt jeder Zeile in der Reihenfolge, die in der OVER (ORDER BY ....) -Klausel definiert ist, eine fortlaufende Nummer hinzu. Also die erste Reihe bekommt # 1, die zweite # 2 und so weiter.

Lesen Sie mehr über CTE's hier: MSDN – Verwenden gemeinsamer Tabellenausdrücke

Lesen Sie mehr über ROW_NUMBER und andere Ranking-functionen hier: MSDN ROW_NUMBER

Der einfachste path, wenn es ein SQL server ist, dann dieser:

 SELECT TOP 3 ROW_NUMBER() OVER(ORDER BY Users.Reputation DESC), Users.Reputation FROM Users 

Aktualisieren:

Ich überprüfte den Abfrageausführungsplan und die innere Reihenfolge durch, die die logische Reihenfolge der Zeilen innerhalb jeder Partition der Ergebnismenge definiert (ich habe in diesem Fall keine spezifizierte Partitionierungsbedingung verwendet), wobei ein sortingsschritt verwendet wird, der gleich ist wie bei einer normalen sorte:

 SELECT Users.Reputation FROM Users ORDER BY Users.Reputation DESC 

Nach diesem Schritt gibt es zwei interessante Schritte: Segment- und Sequenzprojekt. Die zweite sagt, dass es sich um eine übergeordnete datamenge handelt. Die letzten Schritte sind ein TOP und ein SELECT.

Ich bin in den Nachteilen intrested, aber es scheint OK.

Und nur eine Notiz am Ende: mit einem normalen OrderBy mit TOP:

  SELECT TOP 3 Users.Reputation FROM Users ORDER BY Users.Reputation DESC 

Die sorting ist einfacher, aber fast gleich: Sort (Top N sort)