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.

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top