sql - 分段統計前N高的問題

      最近做了一些sql的題,想着總結一下吧,所以就有了下面這篇博文。
      sql中經常會遇到一類需求:需要分段統計前N高。例如:每個班的成績前三,每科的成績前三,每個部門的工資前五等等。
      這類題其實可以分成兩種情況:
      1. 前1高,也就是第一。
      2. 前N高,也就是前三,前五等等。

一、 前1高

第一種解決辦法

      針對分段的字段(每個班的成績前三,那麼每個班就是分段字段),group by以後再根據需求max或者min就可以求出來。但是這種求出來以後,一般只有分段字段和具體的值,如果想要查學生姓名,性別等,還需要再處理(根據具體的值join或者在where中in)。

第二種解決辦法 - over()

      使用over(),排序函數有三種:row_number(),rank(),dense_rank()。因爲只關心第一,所以用哪種都可以。直接用排序函數,over中對分段字段進行partition by,對具體的值進行order by,根據業務需求決定是否desc。然後嵌套子查詢,排序字段進行過濾即可。
      我喜歡這種方法,因爲所有的字段都可以顯示出來,不用像group by那樣那麼麻煩。
      但是mysql8.0以前好像不支持…唉

案例

      光說不練假把式,不過自己寫測試案例太麻煩了,還是參考我做過的題吧: 部門工資最高的員工https://blog.csdn.net/weixin_42845682/article/details/105437193。

二、 前N高

第一種解決辦法

      可以利用子查詢,可以求出,大於每個值的值有多少個。然後用N做過濾,同時配合分段字段就行。(湊合看吧)
      我很不喜歡用這種辦法…感覺可讀性太差了。

第二種解決辦法 - over()

      我還是喜歡這種辦法…
      使用over(),排序函數有三種:row_number(),rank(),dense_rank()。根據具體的業務需求,去決定需要使用哪個。
      直接用排序函數,over中對分段字段進行partition by,對具體的值進行order by,根據業務需求決定是否desc。然後嵌套子查詢,排序字段進行過濾即可。
      同時,推薦想進階的同學看這個: mysql中,實現dense_rank()的效果。 - 不使用dense_rank(),實現編號排序的效果。https://blog.csdn.net/weixin_42845682/article/details/105253070

案例

      光說不練假把式,不過自己寫測試案例太麻煩了,還是參考我做過的題吧: 部門工資前三高的所有員工https://blog.csdn.net/weixin_42845682/article/details/105437449。
      
      
      
      
      
      
      
      
      
      

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章