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

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


锋利的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.


pandas的groupby函数是对数据进行分组操作的一种常用方法。它可以将数据按照一列或多列进行分组,并对每个组进行聚合、转换或其他操作。当需要对分组后的数据进行筛选,只几行时,可以使用head()函数。 在groupby函数中,通过传入多个列名可以按照多列进行分组。例如,假设我们有一个包含学生姓名、学科和成绩的数据集,我们想按照学科和姓名这两列进行分组,并每个组的几行数据。 假设我们已经将数据导入pandas的DataFrame中,可以这样操作: ``` python import pandas as pd # 创建DataFrame data = {'姓名': ['张三', '李四', '王五', '赵六', '刘七', '张三', '李四', '王五', '赵六', '刘七'], '学科': ['语文', '数学', '语文', '数学', '英语', '语文', '数学', '语文', '数学', '英语'], '成绩': [90, 80, 70, 60, 50, 85, 75, 65, 55, 45]} df = pd.DataFrame(data) # 按照学科和姓名进行分组,并两行数据 top2 = df.groupby(['学科', '姓名']).head(2) print(top2) ``` 输出结果为: ``` 姓名 学科 成绩 0 张三 语文 90 1 李四 数学 80 2 王五 语文 70 3 赵六 数学 60 4 刘七 英语 50 5 张三 语文 85 6 李四 数学 75 7 王五 语文 65 8 赵六 数学 55 ``` 通过groupby函数按照学科和姓名进行分组后,再使用head(2)函数每个组的两行数据。结果中会包含每个学科和姓名组合的两行数据。 总结起来,使用pandas的groupby函数按照多列进行分组,再用head()可方便地几行数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值