數據庫面試中的大坑!Group by 與 max聯合使用
相信大家都做過返回各部門中薪水最高的員工信息,是否注意到裏面的細節呢?
由於group by聚合函數的特殊性,會造成聯合其他函數時產生各種各樣的錯誤,尤其max和group by使用最爲頻繁,今天通過mysql案例揭示其背後的錯誤原因,並提出解決方法。首先我們先來了解下group by函數。
1、group by函數的說明:
如表1
執行如下SQL語句:
`SELECT` `name` `FROM` `test` `GROUP` `BY` `name`
如虛擬表3中的數據說明,group by聚合多行同一name下的多個id和number並壓縮在了一行。
詳見https://blog.csdn.net/yulutian/article/details/93247203
2、問題關鍵
由於mysql的表中一行只能對應一行數據,所以纔會造成和max函數混合使用的錯誤。當使用max函數之後,一個group中的多行數據,只會顯示第一行數據,
案例2:
原表salaries的信息
我們現在選擇每個部門下最大工資對應的員工
select max(s.salary) , s.emp_no, s.dp from salaries s group by s.dp order by s.emp_no
查詢的結果!!
注意到部門(dp)7中,最高工資爲員工編號爲10012、10010、10011對應的工資爲700,怎麼會出現10001員工了呢?
如果你還記得group by函數的話,就不難解釋了,以dp分組的虛擬表中的7組員工中一共有4行,第一行就是員工10001,所以該員工就被顯示出來了。
3、解決問題
知道了問題所在,如何解決問題呢?
我們可以瞭解到在使用max(salary)和group by(dp)函數時,只有返回列(salary,dp)是正確對應的,其他的列均不正確,所以可以將這兩列作爲子查詢結果
select ss.emp_no , ss.salary , ss.dp
from
(select max(s.salary) as ms, s.dp from salaries s
group by s.dp order by s.emp_no) as temp
join salaries ss
where ss.salary = temp.ms and ss.dp =temp.dp
order by ss.emp_no;
結果: 可以正確的返回每組中最大工資的員工編號!