今天面試遇到的一道SQL題,憋了半天沒答出來。回家第一件事就是Google答案,但找到的一些文章都不是完全符合題目要求,所以自己建了個測試表來折騰了。
表結構是這樣的:

要求是查出各科總成績最高的學生姓名和總成績。(注:第一名可能重分)
思路大概是根據姓名聚合查詢出name和 sum(score),並根據score排序,再取出score最大的數據。這里有一個坑點,就是成績最高的人可能不止一個,所以max函數和 limit 1 不能實現需求,也是因為這個,才真正了解了MySQL的變量和判斷語句。下面是解題思路:
第一步:聚合查詢name和sum(score),並排序
SELECT `name` ,SUM(score) AS sum_score FROM grade GROUP BY `name` ORDER BY `sum_score` DESC
得到下面的數據
如果不考慮重分的情況,到這一步直接返回第一條數據就完成任務了。
這時候就要用到sql的判斷了,但首先我們要有一個判斷的條件。在這里我是選擇在剛得到的數據基礎上,新增一列rank,記錄排名。具體如下:
第二步:增加排名列
SET @rank = 0; SET @last_score = 0; SELECT *, CASE WHEN @last_score = u.sum_score THEN @rank WHEN @last_score := u.sum_score THEN @rank := @rank + 1 END AS rank FROM (SELECT `name` ,SUM(score) AS sum_score FROM grade GROUP BY `name` ORDER BY `sum_score` DESC) u;
返回數據如下:

這一步用到了mysql中的變量和判斷語句,
第三步:從查詢出的數據中再查出rank等於1的數據
SET @rank = 0; SET @last_score = 0; SELECT `name`,`sum_score` FROM ( SELECT *, CASE WHEN @last_score = u.sum_score THEN @rank WHEN @last_score := u.sum_score THEN @rank := @rank + 1 END AS rank FROM (SELECT `name` ,SUM(score) AS sum_score FROM grade GROUP BY `name` ORDER BY `sum_score` DESC) u ) t where `rank` = 1;
結果如下:

符合我們題目的要求
