mysql 用Group by分组后,取每组的前几条记录的方法和理解

  • Post author:
  • Post category:mysql


转载的,重点是说下自己的理解:


--需求:查询每门课程的前2名成绩


CREATE


TABLE


StudentGrade(


stuId


CHAR


(4),


--学号


subId


INT


,


--课程号


grade


INT


,


--成绩


PRIMARY


KEY


(stuId,subId)


)


GO


--表中数据如下


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'001'


,1,97);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'001'


,2,50);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'001'


,3,70);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'002'


,1,92);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'002'


,2,80);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'002'


,3,30);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'003'


,1,93);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'003'


,2,95);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'003'


,3,85);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'004'


,1,73);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'004'


,2,78);


INSERT


INTO


StudentGrade(stuId,subId,grade)


VALUES


(


'004'


,3,87);


GO


/*


要查询每门课程的前2名成绩


001 1 97


003 1 93


003 2 95


002 2 80


004 3 87


003 3 85


如何实现?


*/


--查看数据


select


*


from


StudentGrade

以下是我的个人理解:

SQL写法:

结果

理解:

核心思路:要算出某人成绩在第几名,可以转换成:算出他一共比多少人成绩高。比如,第一名的人,就没其它人成绩比他更好。第三名的人,就有两个人成绩比他好。

where语句可以理解为,把表中的每一行记录,都去与给定的where条件作对比,满足的再查出来。

也就是有个遍历的过程。

模拟下SQL执行的过程就是,先取出外层a表的第一条记录

执行where中的子查询:

select count(1) from student_grade b where b.subId=

1

and b.grade>=

97

加粗的数据,即从外层a表取出来的。意思是课程1中,有多少个学生的成绩是大于等于97的?97已是最高分了,只有一个。因此满足外层的条件,小于等于2.

接下来取外层表第二条记录:

where子句变成了:

select count(1) from student_grade b where b.subId=1 and b.grade>=93

意思是课程1中,有多少个学生的成绩是大于等于93的?结果是2,因为97和93分都大于等于93分。因此满足外层的条件,小于等于2.这样就取出了每门课的前两名。

接下来取外层表第三条记录:

where子句变成了:

select count(1) from student_grade b where b.subId=1 and b.grade>=92

意思是课程1中,有多少个学生的成绩是大于等于92的?结果是3,因为97、93、92分都大于等于92分。因此

不满足

外层的条件,小于等于2.

以此类推…

扩展一下:

取每组第一名的记录,只需要把下图红框处改为<=1

取每组成绩最低的,只需把下图黑框处改为b.grade<=a.grade



版权声明:本文为junzi528原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。