mysql 取分組資料的前幾名(1)

2021-09-29 06:10:22 字數 2158 閱讀 6510

目前有需求需要取分組資料的前幾名,有如下的解決方案來實現

具體資料庫如下

sql寫法:

select

* from

student_grade as a

where

( select coun ( * ) from student_grade as b where b.subid = a.subid and b.grade >= a.grade ) <= 2

order by

a.subid,

a.grade desc

結果

理解:核心思路:要算出某人成績在第幾名,可以轉換成:算出他一共比多少人成績高。比如,第一名的人,就沒其它人成績比他更好。第三名的人,就有兩個人成績比他好。

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

此外需要注意的是,該方法在有相同的多個資料時,會導致相同結果全部被選中,此時可以考慮採用另外的方法:

select

s2.stuid,

s2.subid,

s2.grade

from

( select

if ( s1.subid = @subid, @rank := @rank + 1, @rank := 1 ) as rank,

@subid := subid as tmp_subid,

s1.stuid,

s1.subid,

s1.grade

from

( select stuid, subid, grade from student_grade order by subid, grade desc ) s1,

( select @subid := null, @rank := 1 ) tmp

) s2

where

s2.rank <= 2

MySql分組取前幾名的寫法

1 準備測試資料 create table tb name varchar 10 val int,memo varchar 20 insert into tb values a 2,a2 a的第二個值 insert into tb values a 1,a1 a的第乙個值 insert into t...

取前幾名的例子

給個例子參考 查詢每門課程的前2名成績 create table studentgrade stuid char 4 學號 subid int,課程號 grade int,成績 primary key stuid,subid go 表中資料如下 insert into studentgrade st...

MySQL 分組後取前幾條

利用group concat和substring index實現,能很好的利用索引,適合大資料。select from yourtable where id in select substring index group concat id order by column 2 desc 1 id f...