2010-12-23 4 views
0

Ich habe die folgenden Tabellen:das Ranking eines Fotos in SQL Erste

Photos [ PhotoID, CategoryID, ... ] PK [ PhotoID ] 
Categories [ CategoryID, ... ] PK [ CategoryID ] 
Votes [ PhotoID, UserID, ... ] PK [ PhotoID, UserID ] 

Ein Foto zu einer Kategorie gehört. Eine Kategorie kann viele Fotos enthalten. Ein Benutzer kann einmal für jedes Foto abstimmen. Ein Foto kann von vielen Benutzern gewählt werden.

Ich möchte die Ränge eines Fotos (durch Zählen, wie viele Stimmen es hat) sowohl insgesamt als auch im Rahmen der Kategorie, zu der das Foto gehört, auswählen.

Die Anzahl der SELECT * FROM Votes WHERE PhotoID = @PhotoID ist die Anzahl der Stimmen, die ein Foto hat. Ich möchte, dass die resultierende Tabelle Spalten für den Gesamtrang und den Rang innerhalb der Kategorie generiert hat, so dass ich die Ergebnisse entweder ordnen kann.

So zum Beispiel, die sich ergebende Tabelle aus der Abfrage sollte wie folgt aussehen:

PhotoID VoteCount  RankOverall  RankInCategory 
1   48    1    7 
3   45    2    5 
19   33    3    1 
2   17    4    3 
7   9    5    5 
... 

... Sie bekommen die Idee. Wie kann ich das erreichen? Bisher habe ich die folgende Abfrage bekam die Stimme zählt zu holen, aber ich brauche die Reihen zu erzeugen, wie gut:

SELECT  PhotoID, UserID, CategoryID, DateUploaded, 
          (SELECT  COUNT(CommentID) AS Expr1 
          FROM   dbo.Comments 
          WHERE  (PhotoID = dbo.Photos.PhotoID)) AS CommentCount, 
          (SELECT  COUNT(PhotoID) AS Expr1 
          FROM   dbo.PhotoVotes 
          WHERE  (PhotoID = dbo.Photos.PhotoID)) AS VoteCount, Comments 
FROM   dbo.Photos 

Antwort

2

Werfen Sie einen Blick auf so etwas wie (RANK (Transact-SQL) und vielleicht DENSE_RANK (Transact-SQL))

SELECT p.PhotoID, 
     ISNULL(v.CountVotes,0) CountVotes, 
     RANK() OVER(ORDER BY ISNULL(v.CountVotes,0) DESC) RankInCategory, 
     RANK() OVER(PARTITION BY p.CategoryID ORDER BY ISNULL(v.CountVotes,0) DESC) RankInCategory 
FROM Photos p LEFT JOIN 
     (
      SELECT PhotoID, 
        COUNT(PhotoID) CountVotes 
      FROM Votes v 
      GROUP BY PhotoID 
     ) v ON v.PhotoID = p.PhotoID 
+0

Erstaunlich, danke. Ich wusste nicht, dass SQL Server eine Funktion wie 'RANK()' hat, die gleiche Elemente gleichrangig darstellt (im Gegensatz zu 'ROW_NUMBER()'). –