Consulta SQL para obtener las "n" puntuaciones más altas de una lista
-
09-06-2019 - |
Pregunta
Me gustaría encontrar las diferentes formas de resolver un problema de la vida real que tuve:Imagínese tener un concurso o un juego durante el cual los usuarios acumulan puntos.Debe crear una consulta para mostrar la lista de usuarios con las mejores puntuaciones "n".
Estoy haciendo un ejemplo para aclarar.Digamos que esta es la tabla de Usuarios, con los puntos obtenidos:
UserId - Points
1 - 100
2 - 75
3 - 50
4 - 50
5 - 50
6 - 25
Si quiero los 3 primeros puntajes, el resultado será:
UserId - Points
1 - 100
2 - 75
3 - 50
4 - 50
5 - 50
Esto se puede realizar en una vista o en un procedimiento almacenado, como desee.Mi base de datos de destino es Sql Server.En realidad resolví esto, pero creo que hay diferentes formas de obtener el resultado...más rápido o más eficiente que el mío.
Solución
No probado, pero debería funcionar:
select * from users where points in
(select distinct top 3 points from users order by points desc)
Otros consejos
Aquí hay uno que funciona: no sé si es más eficiente y es 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
Obviamente, el primer "con" es para configurar los valores, de modo que pueda probar el segundo con y seleccionar el trabajo final; podría comenzar con "con resultados como..." si estuviera consultando una tabla existente.
Qué tal si:
select top 3 with ties points
from scores
order by points desc
No estoy seguro de si "con vínculos" funciona en cualquier otra cosa que no sea SQL Server.
En SQL Server 2005 y versiones posteriores, puede pasar el número "superior" como parámetro int:
select top (@n) with ties points
from scores
order by points desc
En realidad, una modificación del WHERE IN, utilizando una INNER JOIN será mucho más rápida.
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, no creo que funcione según lo solicitado, no estoy muy familiarizado con MS SQL, pero esperaría que devuelva solo 3 filas e ignore el hecho de que 3 usuarios están empatados en el tercer lugar.
Algo como esto debería funcionar:
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
Esta consulta solo seleccionará 3 filas si N es 3, consulte la pregunta."Top 3" debería devolver 5 filas.
@Espo, gracias por comprobar la realidad; se agregó la subselección para corregir eso.
Creo que la respuesta más fácil es:
select userid, points from users
where points in (select distinct top N points from users order by points desc)
Si desea poner eso en un proceso almacenado que toma N como parámetro, entonces tendrá que leer el SQL en una variable y luego ejecutarlo, o hacer el truco de contar filas:
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
o
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
Ambos ejemplos asumen SQL Server y no han sido probados.
@Matt Hamilton
Su respuesta funciona con el ejemplo anterior, pero no funcionaría si el conjunto de datos fuera 100, 75, 75, 50, 50 (donde devolvería solo 3 filas).TOP CON LAZOS sólo incluye los lazos de la última fila devuelta...
Crucible lo consiguió (suponiendo que SQL 2005 sea una opción).
Oye, encontré todas las otras respuestas un poco e ineficientes, mi respuesta sería:
select * from users order by points desc limit 0,5
esto generará los 5 mejores puntos
Prueba esto
select top N points from users order by points desc