這篇文章主要介紹MySQL中GROUP BY分組排序獲取topN相關(guān)的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
成都創(chuàng)新互聯(lián)于2013年創(chuàng)立,先為城廂等服務(wù)建站,城廂等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為城廂企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
MySQL VERSION : 5.5.45
ENGINE : InnoDB
問題描述:
獲取成績表中每位同學(xué)成績排名前n的記錄。
表結(jié)構(gòu):
表數(shù)據(jù):
法一(用戶變量):
①首先我先得到每組排名的所有結(jié)果
點擊(此處)折疊或打開
select @gp_row:=if(@name=name,@gp_row+1,1) as gp_row,@name:=name,id,name,grade from td ,(select @gp_row:=0,@name:='') as temp order by name,grade desc;
得到如下結(jié)果:
②在把該結(jié)果作為中間表,查詢top N的數(shù)據(jù)
點擊(此處)折疊或打開
select id ,name ,grade from (select@gp_row:=if(@name=name,@gp_row+1,1)as gp_row,@name:=name,id,name,gradefrom td,(select@gp_row:=0,@name:='')as temporderby name,gradedesc)as tb_gp_rankwhere gp_row<=2;
得到結(jié)果如下:
③查看執(zhí)行計劃
我們可以看到,對td使用了一個全表掃面(和索引字段相關(guān)和select,where字段相關(guān)等),并且用到了using filesort,當表記錄數(shù)過多的時候效率肯定不高,這也沒辦法,數(shù)據(jù)無序以及沒有相關(guān)索引以及select字段還有一些關(guān)系,但是這種查詢方式基本可以滿足這一類型的基本需求。
法二(union):
①在知道分組字段的情況下,可以使用union合并各組結(jié)果集
點擊(此處)折疊或打開
(select id ,name ,grade from td where name='tab' order by grade desc limit 2) union (select id ,name ,grade from td where name='lily' order by grade desc limit 2);
②查看執(zhí)行計劃
可以發(fā)現(xiàn),在此種表結(jié)構(gòu)下,union操作會掃n次全表(和索引字段相關(guān)),即多少個union結(jié)果集就有多少次。這種方法還需知道需要分組排序的具體的字段值,使用上有限制。
法三(子查詢):
①子查詢的方式適合選擇并列top N的情況
點擊(此處)折疊或打開
select a.* from td a where (select count(*) from td where td.name=a.name and td.grade>a.grade)<2 order by name,grade desc;
此時在插入一條數(shù)據(jù) insert into td select null,'tab',76;
再次查詢可得結(jié)果如下
也就是說在排序之后最后一條數(shù)據(jù)如果有重復(fù)的則都會作為結(jié)果集返回,即第一次查詢的結(jié)果,tab 成績?yōu)?4位于第二名的數(shù)據(jù)有兩條。
法四(join連接):即把子查詢轉(zhuǎn)換為join連接,這里就不在測試。
以上是“MySQL中GROUP BY分組排序獲取topN相關(guān)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!