SQL分组查询问题(获取每个班前三名)

时间:2022-09-16 12:47:51
例如这样一个表tb
id|class|marks
1|1|100
2|1|99
3|2|97
4|3|85
5|2|90
....
还有很多。
我想在一次查询当中,获取每个班的前三名。怎么实现????????

14 个解决方案

#1


select t.* from tb t where id in(select top 3 id from tb where class=t.class order by marks desc) order by class,marks desc

#2


select *
from tb t
where (select count(1)+1 from tb where class=t.class and marks>t.marks)<=3

#3


select * from (select *,row_number() over(partition by class order by marks desc)as [order] from tb) where [order]<4

#4


SELECT * FROM TB T WHERE CHECKSUM(*) IN (SELECT TOP 3  CHECKSUM(*) FROM TB WHERE CLASS=T.CLASS ORDER BY MARKS DESC)

							     

#5


select t.* from tb t where id in(select top 3 id from tb where class=t.class order by marks desc) order by class,marks desc

#6


--SQL2005适用
if object_id('tb') is not null drop table tb
go
create table tb(id int,class int,marks int)

insert tb
select 1,1,100 union all
select 2,1,99 union all
select 3,1,96 union all
select 4,1,90 union all
select 5,2,97 union all
select 6,2,85 union all
select 7,2,93 union all
select 8,2,85 union all
select 9,3,90 
--如果并列都算用RANK(),排除并列用DENSE_RANK()
select *
from (select *,RANK() OVER(PARTITION BY class ORDER BY marks desc) as [Order] FROM tb) a
where a.[Order] between 1 and 3

#7


后面几个还需要加上order by class,marks desc

#8


--用dense_rank
select *
from (select *,dense_RANK() OVER(PARTITION BY class ORDER BY marks desc) as [Order] FROM tb) a
where [Order]<=3

#9


if object_id('tb') is not null drop table tb
create table tb(id int,class int,marks int)

insert tb
select 1,1,100 union all
select 2,1,99 union all
select 3,1,96 union all
select 4,1,90 union all
select 5,2,97 union all
select 6,2,85 union all
select 7,2,93 union all
select 8,2,85 union all
select 9,3,90 
select bb.* from (select *,row_number() over (partition by class order by marks) rank from tb) bb
where bb.rank<=3 order by bb.class,bb.rank

id          class       marks       rank
----------- ----------- ----------- --------------------
4           1           90          1
3           1           96          2
2           1           99          3
6           2           85          1
8           2           85          2
7           2           93          3
9           3           90          1

(7 行受影响)

#10


人齐结贴

#11


引用楼主 Hajoio 的帖子:
例如这样一个表tb 
id|class|marks 
1|1|100 
2|1|99 
3|2|97 
4|3|85 
5|2|90 
.... 
还有很多。 
我想在一次查询当中,获取每个班的前三名。怎么实现????????


select t.* from tb t where marks in (select top 3 marks from tb where class = t.class order by marks desc)

#12


--sql 2005
select id,class,marks from
(
select t.* , px = row_number() rank(partition class order by marks desc) from tb t
) m
where px <= 3

#13


大家都好积极啊~~哈哈~~~
不过,这些好像是mssql才行的~~
那个mysql如何实现呢?

#14


1楼的速度很快,而且是正确的!不过本人是mysql有些问题。
2楼的代码自己没有看懂,但是,在mysql下是正确的~~~~~
后面呢…………没有细细看了!基础不行!!!
分少,大家多多包涵!

#1


select t.* from tb t where id in(select top 3 id from tb where class=t.class order by marks desc) order by class,marks desc

#2


select *
from tb t
where (select count(1)+1 from tb where class=t.class and marks>t.marks)<=3

#3


select * from (select *,row_number() over(partition by class order by marks desc)as [order] from tb) where [order]<4

#4


SELECT * FROM TB T WHERE CHECKSUM(*) IN (SELECT TOP 3  CHECKSUM(*) FROM TB WHERE CLASS=T.CLASS ORDER BY MARKS DESC)

							     

#5


select t.* from tb t where id in(select top 3 id from tb where class=t.class order by marks desc) order by class,marks desc

#6


--SQL2005适用
if object_id('tb') is not null drop table tb
go
create table tb(id int,class int,marks int)

insert tb
select 1,1,100 union all
select 2,1,99 union all
select 3,1,96 union all
select 4,1,90 union all
select 5,2,97 union all
select 6,2,85 union all
select 7,2,93 union all
select 8,2,85 union all
select 9,3,90 
--如果并列都算用RANK(),排除并列用DENSE_RANK()
select *
from (select *,RANK() OVER(PARTITION BY class ORDER BY marks desc) as [Order] FROM tb) a
where a.[Order] between 1 and 3

#7


后面几个还需要加上order by class,marks desc

#8


--用dense_rank
select *
from (select *,dense_RANK() OVER(PARTITION BY class ORDER BY marks desc) as [Order] FROM tb) a
where [Order]<=3

#9


if object_id('tb') is not null drop table tb
create table tb(id int,class int,marks int)

insert tb
select 1,1,100 union all
select 2,1,99 union all
select 3,1,96 union all
select 4,1,90 union all
select 5,2,97 union all
select 6,2,85 union all
select 7,2,93 union all
select 8,2,85 union all
select 9,3,90 
select bb.* from (select *,row_number() over (partition by class order by marks) rank from tb) bb
where bb.rank<=3 order by bb.class,bb.rank

id          class       marks       rank
----------- ----------- ----------- --------------------
4           1           90          1
3           1           96          2
2           1           99          3
6           2           85          1
8           2           85          2
7           2           93          3
9           3           90          1

(7 行受影响)

#10


人齐结贴

#11


引用楼主 Hajoio 的帖子:
例如这样一个表tb 
id|class|marks 
1|1|100 
2|1|99 
3|2|97 
4|3|85 
5|2|90 
.... 
还有很多。 
我想在一次查询当中,获取每个班的前三名。怎么实现????????


select t.* from tb t where marks in (select top 3 marks from tb where class = t.class order by marks desc)

#12


--sql 2005
select id,class,marks from
(
select t.* , px = row_number() rank(partition class order by marks desc) from tb t
) m
where px <= 3

#13


大家都好积极啊~~哈哈~~~
不过,这些好像是mssql才行的~~
那个mysql如何实现呢?

#14


1楼的速度很快,而且是正确的!不过本人是mysql有些问题。
2楼的代码自己没有看懂,但是,在mysql下是正确的~~~~~
后面呢…………没有细细看了!基础不行!!!
分少,大家多多包涵!