SQL-Abfrage, um die oberen "n" erzielt aus der Liste
-
09-06-2019 - |
Frage
Ich möchte zu finden, die die verschiedenen Möglichkeiten zur Lösung eines real life problem, das ich hatte:stellen Sie sich auf einen Wettbewerb oder ein Spiel, in dem der Benutzer Punkte sammeln.Sie müssen eine Abfrage erstellen, um die Liste der Benutzer mit der best "n" erzielt.
Ich mache ein Beispiel zu klären.Lassen Sie uns sagen, dass dies die Benutzer-Tabelle, mit der die gesammelten Punkte:
UserId - Points
1 - 100
2 - 75
3 - 50
4 - 50
5 - 50
6 - 25
Wenn ich die top 3 erzielt, das Ergebnis wird sein:
UserId - Points
1 - 100
2 - 75
3 - 50
4 - 50
5 - 50
Dies kann realisiert werden in eine Ansicht oder eine gespeicherte Prozedur, wie Sie wollen.Mein Ziel-db ist Sql Server.Eigentlich habe ich gelöst, aber ich denke, es gibt verschiedene Weise erhalten Sie das Ergebnis...schneller oder effektiver ist als meins.
Lösung
Ungetestet, sollte aber funktionieren:
select * from users where points in
(select distinct top 3 points from users order by points desc)
Andere Tipps
Hier ist eine, die funktioniert - ich weiß nicht, ob es ist mehr effiziente, und es ist SQL Server 2005+
with scores as (
select 1 userid, 100 points
union select 2, 75
union select 3, 50
union select 4, 50
union select 5, 50
union select 6, 25
),
results as (
select userid, points, RANK() over (order by points desc) as ranking
from scores
)
select userid, points, ranking
from results
where ranking <= 3
Offensichtlich ist der erste "mit" ist eingerichtet, die Werte, so können Sie testen, die zweite und endgültige wählen Sie funktionieren - Sie könnte beginnen bei "mit Ergebnissen als...", wenn Sie der Abfrage eine vorhandene Tabelle.
Wie wäre es mit:
select top 3 with ties points
from scores
order by points desc
Nicht sicher, ob "mit Beziehungen" arbeitet an etwas anderen SQL-Server.
Auf SQL Server 2005 and up, die Sie übergeben können, die "top" - Reihe als int-parameter:
select top (@n) with ties points
from scores
order by points desc
Eigentlich eine Veränderung der WHERE-IN, mit einem INNER JOIN werden sehr viel schneller.
SELECT
userid, points
FROM users u
INNER JOIN
(
SELECT DISTINCT TOP N
points
FROM users
ORDER BY points DESC
) AS p ON p.points = u.points
@bosnic, ich glaube nicht, dass es funktionieren wird, wie verlangt, ich bin nicht so vertraut mit MS SQL, aber ich würde erwarten, dass es wieder nur 3 Zeilen, und ignorieren die Tatsache, dass 3-Benutzer gebunden sind, für den 3. Platz.
So etwas sollte funktionieren:
select userid, points
from scores
where points in (select top 3 points
from scores
order by points desc)
order by points desc
@Rob#37760:
select top N points from users order by points desc
Diese Abfrage wird nur wählen Sie 3 Zeilen, wenn N 3 ist, finden Sie unter der Frage."Top 3" zurückgeben sollte, in 5 Zeilen.
@Espo Dank für die reality-check - Hinzugefügt wurde die sub-wählen Sie die richtige für, dass.
Ich denke, die einfachste Antwort ist:
select userid, points from users
where points in (select distinct top N points from users order by points desc)
Wenn Sie möchten, dass es in eine gespeicherte Prozedur nimmt N als parameter, dann werden Sie entweder zu tun haben, Lesen Sie die SQL in einer Variablen, dann führen Sie es, oder tun die Zeilenanzahl trick:
declare @SQL nvarchar(2000)
set @SQL = "select userID, points from users "
set @SQL = @SQL + " where points in (select distinct top " + @N
set @SQL = @SQL + " points from users order by points desc)"
execute @SQL
oder
SELECT UserID, Points
FROM (SELECT ROW_NUMBER() OVER (ORDER BY points DESC)
AS Row, UserID, Points FROM Users)
AS usersWithPoints
WHERE Row between 0 and @N
Beide Beispiele gehen davon aus SQL Server und wurde noch nicht getestet.
@Matt Hamilton
Ihre Antwort funktioniert bei dem obigen Beispiel würde aber nicht funktionieren, wenn Sie die Daten set 100, 75, 75, 50, 50 (wo würde es wieder nur 3 Zeilen).TOP MIT KRAWATTEN nur die Bindungen der letzten Zeile zurückgegeben...
Tiegel habe es (vorausgesetzt, SQL 2005 ist eine option).
Hey, ich fand alle anderen Antworten etwas lang und ineffizient Meine Antwort wäre:
select * from users order by points desc limit 0,5
hierdurch werden die top 5 Punkte
Versuchen Sie, diese
select top N points from users order by points desc