在面試的時候我經常會給畢業生出這樣一道SQL題:
有一張表studentgrade,包含三個字段name,subject和grade,如下所示:
name subject grade
a 數學 99
b 英語 67
a 英語 77
題目要求應試者寫出sql,查詢每個人的最高分和最高分的科目,比如
a 數學 99
下面分析這個SQL的查詢方法,分組函數是最常使用的,下面的分組函數可以得到最高分,姓名
select name,max(grade) from studentgrade group by name;
這樣顯然得不到具體的科目,要得到科目怎么辦呢?使用臨時表就是一個方案:
select b.name,b.grade,b.subject from
(select name, max(grade) grade from studentgrade group by name ) a,
studentgrade b
where a.name = b.name and a.grade = b.grade;
如果是需要查詢每個人前三個最高分的成績和科目呢?分組函數ms就無能為力了。下面是是幾個不錯的方式:
1、對每條記錄進行檢驗,查詢這條記錄是不是排在前三位的
select a.* from studentgrade a where 3 > (select count(*) from studentgrade where name=a.name and grade< a.grade) order by a.name,a.grade;
為提高查詢效率,在name和grade上面建立聯合索引。
2、先把每個同學最大的三個科目分數查詢出來形成一個集合,然后對每條記錄進行檢驗,查看是否在這個集合里面。這種方式是mysql特有的,使用了top關鍵字。
select a.* from studentgrade a where grade in (select top 3 grade from studentgrade where
name=a.name order by grade) order by a.name,a.grade;
3、和第一種方式差不多,但使用的exists關鍵字。
select a.* from studentgrade a where exists (select count(*) from studentgrade where name=a.name and grade<a.grade having Count(*) < 2) order by a.name;