MySQL查詢top N記錄


     下面以查詢每門課程分數最高的學生以及成績為例,演示如何查詢 top N記錄。下圖是測試數據,表結構和相關 insert 腳本見《常用SQL之日期格式化和查詢重復數據》。

 

使用自連接【推薦】 

select a.name,a.course,a.score from test1 a, (select course,max(score) score from test1 group by course) b WHERE a.course=b.course and a.score=b.score;

 

     執行后,結果集如下:

 

 

 

使用相關子查詢

 

select name,course,score from test1 a where a.score=(select max(score) from test1 where a.course=test1.course); 或者 select name,course,score from test1 a where not exists(select 1 from test1 where a.course=course and a.score < score); 或者 select a.* from test1 a where 1>(select count(*) from test1 where course=a.course and score>a.score);

 

 

    結果集同上圖。需要注意的是如果最高分有多條,會全部查出!

 

TOP N(N>1)

     以N=2為例,演示如何查詢TOP N(N>1)。

使用union all

     如果結果集比較小,可以用程序查詢單個分組結果后拼湊,也可以使用 union all。

(select name,course,score from test1 where course='語文' order by score desc limit 2) union all (select name,course,score from test1 where course='數學' order by score desc limit 2) union all (select name,course,score from test1 where course='英語' order by score desc limit 2);

 

 

自身左連接

select a.name,a.course,a.score from test1 a left join test1 b on a.course=b.course and a.score<b.score group by a.name,a.course,a.score having count(b.id)<2
order by a.course,a.score desc;

 

 

     兩個表做連接查詢,笛卡爾積,然后用having count(b.id)篩選出比當前條數大的條數。

自關聯+count()

select a.* from test1 a where 2>(select count(*) from test1 where course=a.course and score>a.score) order by a.course,a.score desc;

    思路就是判斷每一條記錄,比a中當前記錄大的條數是否為2,如果有2條比較大,則符合。篩選出全部記錄,最后按課程和學分排序。但是子查詢進行了n次count(*)計算,因此性能極差。

半連接+count()+having

select * from test1 a where exists(select count(*) as sum from test1 b where b.course=a.course and b.score>a.score having sum <2) order by a.course,a.score desc;

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM