1. 程式人生 > >MAX()KEEP(DENSE_RANK FIRST/LAST) 獲取最大值相對應的某個欄位,非常非常實用的一個函式

MAX()KEEP(DENSE_RANK FIRST/LAST) 獲取最大值相對應的某個欄位,非常非常實用的一個函式

場景

在業務資料中可能遇到這樣的需求。希望獲取部門內年齡最小的人中,工資最高的記錄。此時就需要使用KEEP(DENSE_RANK FIRST/LAST)來處理資料了。

使用

首先構造一下臨時資料。

  1. WITH workers AS(    
  2.   SELECT'DOM1' dept, 'zhangsan' names , 23 age, 4000 salaries FROM dual UNIONALL
  3.   SELECT'DOM1' dept, 'lisi' names     , 35 age, 9000 salaries FROM dual UNIONALL
  4.   SELECT'DOM2' dept, 'wangwu' names   , 26 age, 6500 salaries 
    FROM dual UNIONALL
  5.   SELECT'DOM2' dept, 'maliu' names    , 28 age, 6000 salaries FROM dual UNIONALL
  6.   SELECT'DOM2' dept, 'zhaoqi' names   , 26 age, 5000 salaries FROM dual UNIONALL
  7.   SELECT'DOM1' dept, 'liba' names     , 23 age, 3000 salaries FROM dual     
  8. )  

在這六條資料中,我們期望的資料是:(DOM1,4000)和(DOM2,6500)。


我們的sql如下:

  1. SELECT w.dept, 
    MAX(w.salaries) KEEP(DENSE_RANK FIRSTORDERBY w.age) max_salary FROM workers w WHERE 1=1 GROUPBY dept;  


此圖就是我們的查詢結果。

解釋

KEEP

keep的意思就是“保持”,會保持滿足括號內條件的記錄,用ORDER BY 後自然會有FIRST和LAST了。

DENSE_RANK

DENSE_RANK是排序策略。例如,它會將兩個第二名排在第一名之後,之後還是第三名排在第二名之後。

FIRST/LAST

FIRST/LAST就是對資料進行篩選了。這裡我們篩選age最小的記錄。當然不止一條了。然後使用MAX()選取最大salaries了。

延伸

同樣的,年齡最大人中的最低工資查詢如下:

  1. SELECT w.dept, MIN(w.salaries) KEEP(DENSE_RANK LASTORDERBY w.age) min_salary FROM workers w WHERE 1=1 GROUPBY dept;