SQL查询以从列表中获得最高的" n"分

时间:2020-03-05 18:45:55  来源:igfitidea点击:

我想找到解决现实生活中问题的不同方法:想象一下在比赛或者游戏中用户收集积分。我们必须构建一个查询以显示得分最高的" n"用户列表。

我正在举一个例子来澄清。假设这是"用户"表,并获得了积分:

UserId - Points
1      - 100
2      -  75
3      -  50
4      -  50
5      -  50
6      -  25

如果我想获得前三名的分数,结果将是:

UserId - Points
1      - 100
2      -  75
3      -  50
4      -  50
5      -  50

我们可以根据需要在视图或者存储过程中实现这一点。我的目标数据库是Sql Server。其实我已经解决了这个问题,但是我认为有不同的方法来获得结果……比我的更快或者更有效。

解决方案

回答

未经测试,但应该可以工作:

select * from users where points in
(select distinct top 3 points from users order by points desc)

回答

@bosnic,我认为这不能按要求工作,我对MS SQL不太熟悉,但我希望它仅返回3行,而忽略3个用户并列第3位这一事实。

这样的事情应该起作用:

select userid, points 
   from scores 
   where points in (select top 3 points 
                       from scores 
                       order by points desc) 
   order by points desc

回答

@Espo感谢现实检查,添加了子选择来更正此问题。

我认为最简单的回应是:

select userid, points from users
where points in (select distinct top N points from users order by points desc)

如果要将其放在以N为参数的存储过程中,则必须将SQL读入变量然后执行它,或者执行行计数技巧:

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

或者

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

这两个示例均假定使用SQL Server,并且尚未经过测试。

回答

@ Rob#37760:

select top N points from users order by points desc

如果N为3,此查询将仅选择3行,请参阅问题。 "前3名"应返回5行。

回答

怎么样:

select top 3 with ties points 
from scores
order by points desc

不知道"有关系"是否可以在其他SQL Server上使用。

在SQL Server 2005及更高版本上,我们可以将" top"数字作为int参数传递:

select top (@n) with ties points 
from scores
order by points desc

回答

这是一种有效的方法,我不知道它是否更有效,它是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

显然,第一个" with"是设置值,因此我们可以测试第二个with,如果要查询现有表,则可以从" with with as ..."开始最终选择工作。

回答

@马特·汉密尔顿

答案适用于上面的示例,但如果数据集为100、75、75、50、50(仅返回3行),则该命令将无效。 TOP WITH TIES仅包含返回的最后一行的领带...

回答

坩埚就做到了(假设可以选择SQL 2005)。

回答

实际上,使用INNER JOIN对WHERE IN进行修改会快得多。

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

回答

试试这个

select top N points from users order by points desc