在面試的時候我經常會給畢業生出這樣一道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;