group by分组后,取每组的前几行

本文介绍如何使用SQL从分组数据中选取每组的前几条记录,通过表的自身关联和子查询两种方法实现,并给出具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


锋利的SQL:从分组中取前几行数据

sql 用Group by分组后,取每组的前几条记录


本文由以上两篇原文整理得出,请点击以上链接去到原文


原理是表的自身关联

下面的语句用于创建示例表:

CREATE TABLE Students

(ClassID int,

 StuNamechar(10),

 Achi int);

INSERT INTO Students

VALUES(1, '张山', 100),

      (1, '李明', 90),

      (1, '王磊', 95),

      (2, '孙科', 100),

      (2, '赵强', 80),

      (2, '王智', 90),

      (3, '李海', 95);


1.使用联接获取前几行

如果将Students表打开两次,将一个考生与其大于或等于自己成绩的考生联接,我们看看会得到什么样的结果。参考下面的语句:

SELECT S1.*, S2.*

FROM Students AS S1

  INNER JOINStudents AS S2

    ONS1.ClassID = S2.ClassID

      ANDS2.Achi >= S1.Achi

ORDER BY S1.ClassID, S1.Achi DESC;

结果如表2所示。

2                                                                       联接结果

S1.ClassID

S1.StuName

S1.Achi

S2.ClassID

S2.StuName

S2.Achi

1

张山     

100

1

张山     

100

1

王磊     

95

1

张山     

100

1

王磊     

95

1

王磊     

95

1

李明     

90

1

张山     

100

1

李明     

90

1

李明     

90

1

李明     

90

1

王磊     

95

2

孙科     

100

2

孙科     

100

2

王智     

90

2

孙科     

100

2

王智     

90

2

王智     

90

2

赵强     

80

2

孙科     

100

2

赵强     

80

2

赵强     

80

2

赵强     

80

2

王智     

90

3

李海     

95

3

李海     

95

从上表中可以看出,1班中的第1名张山有1条记录,第2名王磊有2条记录,第3名有3条记录。因此,我们可以使用下面的语句来获取每班中前2名的考生。查询结果如表3所示。

SELECT S1.ClassID, S1.Achi, MAX(S1.StuName) ASStuName

FROM Students AS S1

  INNER JOINStudents AS S2

    ONS1.ClassID = S2.ClassID

      ANDS2.Achi >= S1.Achi

GROUP BY S1.ClassID, S1.Achi  

HAVING COUNT(*) <=2

ORDER BY S1.ClassID, S1.Achi DESC;

3                                                             每班中前2名的考生

ClassID

Achi

StuName

1

100

张山

1

95

王磊

2

100

孙科

2

90

王智

3

95

李海



2. 使用子查询实现

select * from student s1
where (select COUNT(*) from student where ClassID=s1.ClassID and Achi>=s1.Achi) <=2

这一个的本质其实也是表的自身内关联,子查询里的student相当于"使用联接获取前几行"中例子的s1,"select * from student s1"中的student相当于"使用联接获取前几行"中例子的s2.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值