以下是您的场景的一些示例数据。参赛者的表,以及所做的尝试。将每个人的尝试放在自己的线路上,这样您就可以看到每个人明显不同的尝试。
create table contestants
( id int identity(1,1) not null,
personName nvarchar(10) )
insert into contestants ( personName )
values ( 'Bill' ), ('Mary'), ('Jane' ), ('Mark')
create table attempts
( id int identity(1,1) not null,
contestantid int not null,
score int not null )
insert into attempts ( contestantid, score )
values
( 1, 72 ), ( 1, 88 ), (1, 81 ),
( 2, 83 ), ( 2, 88 ), (2, 79), (2,86),
( 3, 94 ),
( 4, 79 ), (4, 87)
现在,简单的前提是每个参赛者的最佳分数,这是每个参赛者得分的简单 MAX()。
select
contestantid,
max( score ) highestScore
from
attempts
group by
contestantid
以上查询的结果就是最终排名的BASIS。所以我将该查询作为 FROM 源。因此,from 不是表格,而是上述查询的结果,我将其别名为“PreAgg”,用于每个参赛者的预聚合。
select
ContestantID,
c.personName,
DENSE_RANK() OVER ( order by HighestScore DESC ) as FinalRank
from
(select
contestantid,
max( score ) highestScore
from
attempts
group by
contestantid ) preAgg
JOIN Contestants c
on preAgg.contestantid = c.id
加入参赛者很容易提取名称,但现在看看 DENSE_RANK() 子句。由于没有按分数分组,例如奥运会有一项特定的运动,并且每项运动都有最高的排名,我们不需要“PARTITION”子句。
ORDER BY 子句是您想要的。在这种情况下,来自预聚合查询的 HighestScore 列并希望它按 DESCENDING 顺序排列,因此 HIGHEST 分数位于顶部并向下。 “as”给它最后的列名。
DENSE_RANK() OVER ( order by HighestScore DESC ) as FinalRank
Results
ContestantID personName FinalRank
3 Jane 1
1 Bill 2
2 Mary 2
4 Mark 3
现在,如果您只想要一个限制,例如前 3 名,而您实际上有 20 多个竞争对手,只需在 where 类的地方再结束一次
select * from
(
select
ContestantID,
c.personName,
DENSE_RANK() OVER ( order by HighestScore DESC ) as FinalRank
from
(select
contestantid,
max( score ) highestScore
from
attempts
group by
contestantid ) preAgg
JOIN Contestants c
on preAgg.contestantid = c.id ) dr
where
dr.FinalRank < 3