2008-09-01 66 views
6

我想找到解决现实生活问题的不同方式:想象要举办比赛或游戏,期间用户收集点。您必须建立查询以显示具有最佳“n”分数的用户列表。SQL查询从列表中获得最高的“n”分数

我正在做一个例子来澄清。比方说,这是用户表,用点获得:

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

如果我想的前3名的分数,其结果将是:

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

这可以在视图或实现存储过程,只要你想。我的目标数据库是Sql Server。其实我解决了这个问题,但我认为有不同的方法来获得结果...比我的更快或更有效率。

回答

9

未经检验的,但应该工作:

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

@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 
0

@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并没有经过测试。

0

@罗布#37760:

select top N points from users order by points desc 

这个查询只能选择3行,如果N为3,看问题。 “前3名”应该返回5行。

1

关于如何:

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

不知道是否 “有关系” 的作品上的任何其他的SQL Server。

在SQL Server 2005和了,你可以通过“顶”号作为一个int参数:

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

这里有一个工程 - 我不知道这是否是更高效,它的SQL服务器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 

显然,第一个“用”是设置的值,这样你就可以测试第二位,并最终选择的工作 - 你可以在“结果如......”开始,如果你是查询现有的表格。

+0

我有一个类似的问题,并试图使用MAX,然后我读你的回答并记住了DENSE_RANK。为我节省了很多时间。 – DataGirl 2012-06-21 20:49:47

0

@马特汉密尔顿

你的答案可与上面的例子,但也不会工作,如果数据集为100,75,75,50,50(它会返回只有3行)。 TOP WITH WITH TIES只包括返回的最后一行的关系...

0

坩埚得到它(假设SQL 2005是一个选项)。

0

实际上,使用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 
0

试试这个

select top N points from users order by points desc 
0

嘿,我发现所有的其他的答案有点长,效率低下 我的答案是:

select * from users order by points desc limit 0,5

这将使前5分