使用的示例表
學生表----student
表結構
數據
查詢方法
一、第一種方法
我認為這是比較傳統,比較容易理解的一種方式,使用自連接,並在連接條件中作比較,之后再對查詢條件分組統計,排序。
select a.id,a.class,a.source from student a left join student b on a.class=b.class and a.source<=b.source group by a.class,a.source order by a.class,a.source
結果:
分析一下查詢過程:
1、自連接並使用比較條件
select a.id,a.class,a.source asource,b.source bsource from student a left join student b on a.class=b.class and a.source<=b.source order by a.class,a.source
查詢結果:
以上查詢數據可以看出,每個班等於或比每一個asource分數多bsource有幾條數據,最終,最小的asource會有一個班級人數的數據條數,最大的asource只會有一條數據。這就是排序的依據。
之后,對數據分組。
2、對數據進行分組
select a.id,a.class,a.source asource,count(a.source) from student a left join student b on a.class=b.class and a.source<=b.source group by a.class,a.source order by a.class,a.source
查詢結果:
以上數據已經可以直觀的看出數據被排序后的結果。
3、對分組后的數據截取前N條或后N條
a、首先是保留前N條數據,使用having。
select a.id,a.class,a.source asource,count(a.source) from student a left join student b on a.class=b.class and a.source<=b.source group by a.class,a.source having count(a.source)<=3 order by a.class,a.source
查詢結果:
這樣截取到的每個班最高的三個分數,因為比較條件是:a.source<=b.source,導致asource最大的分數只有一條,最小的有最多的條數,所以在使用having獲得統計數最少的三條數據時,會得到三個最高分。
如果要得到最低的三個分數的數據,就要保證最小的分數有最少的數據(不一定是一條,當有兩個最高分)。因為a.source<=b.source比較條件是相互的,所以只需要將asource參與的查詢換成bsource,就可以實現獲得最少分數的需求。
b、獲得后N條數據
select a.id,a.class,b.source bsource,count(b.source) from student a left join student b on a.class=b.class and a.source<=b.source group by a.class,b.source having count(b.source)<=3 order by a.class,b.source
查詢結果:
二、第二種方法-----只用於分組排序后取前N條數據
1、分組后取前N或后N條,關鍵在於比較,通過where倆控制查詢條數
最大的前3條數據
select * from student as a where 3>(select count(*) from student where class=a.class and source>a.source) ORDER BY class ,source desc
查詢結果:
最小的前3條數據
select * from student as a where 3>(select count(*) from student where class=a.class and source<a.source) ORDER BY class ,source
查詢結果:
這種查詢方式,某些邏輯無法理解。