问题描述
嗨,我有一张看起来像这样的桌子
StudentID | ParentID | 排名 |
---|---|---|
1 | 11 | 1 |
1 | 15 | 5 |
1 | 16 | 6 |
2 | 21 | 1 |
2 | 22 | 2 |
3 | 31 | 1 |
3 | 37 | 7 |
3 | 38 | 8 |
4 | 41 | 1 |
4 | 42 | 2 |
所以我只想提取每个学生的前 2 个排名,结果看起来像:
StudentID | ParentID | 排名 |
---|---|---|
1 | 11 | 1 |
1 | 15 | 5 |
2 | 21 | 1 |
2 | 22 | 2 |
3 | 31 | 1 |
3 | 37 | 7 |
4 | 41 | 1 |
4 | 42 | 2 |
这样做的最佳方法是什么?让事情变得复杂的是,每个学生都有一个排名为 1 的家长,但不是每个学生都有一个排名为 2 的家长。我将使用什么 sql 语句来拉出 1 之后的下一个排名家长?
解决方法
规范的解决方案是使用 row_number()
:
select t.*
from (select t.*,row_number() over (partition by studentid order by rank) as seqnum
from t
) t
where seqnum <= 2;
在某些情况下,使用起来可能会更快:
select t.*
from t
where t.rank in (select top (2) t2.rank
from t t2
where t2.studentid = t.studentid
order by rank asc
) ;
我认为,如果每个学生有很多排名的学生很少,并且您在 studentid,rank
上有索引,这可能会有更好的表现。