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