【Orcale】分析函數 OVER(PARTITION BY... ORDER BY...)的講解


https://blog.csdn.net/east_mrchiu/article/details/70183428

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/East_MrChiu/article/details/70183428

OVER(PARTITION BY... ORDER BY...)的使用說明和意義

這個函數長這個樣子:OVER(PARTITION BY... ORDER BY...)

顧名思義,PARTITION 中文是分割的意思,ORDER 是排序的意思,所以翻譯一下就是先把一組數據按照制定的字段進行分割成各種組,然后組內按照某個字段排序。

以實際案例來說明這個函數的使用,

首先,我們先看一組普通排序的數據:

然后對其進行新加一個偽劣ROWNUM,看看數據原本的順序:

OVER(ORDER BY ...)的意思是以按照某個字段排序,所以和直接對表的order by效果是一樣的:

這里就顯示了OVER(ORDER BY ...)的第一個功能,就是對新查詢得到的數據進行重新編號,即RNO的值,由於這里沒有PARTITION BY...,所以可以比作整個列就是一個大塊,然后對大塊的內容進行排序,這個時候再加上PARTITION BY...,查詢結果:

它會按照制定的字段,把相同值的排在一起,分為一個塊,也就是分組,然后組內排序編號,這樣你就可以取不同組內的任意第幾個值,類似於TOP-N的分析。

在這里over之前使用的函數是ROW_NUMBER(),就是對數據的編號。

 

與OVER(PARTITION BY... ORDER BY...)匹配使用的函數

row_number() over()、rank() over()和dense_rank() over()

在上面的例子里,使用ROW_NUMBER()可以對數據編號,但是有一個問題,例子中的MI_ID是不可以重復的,如果在可以重復的情況下,就有並列的情況,這樣就無法取出並列的數據,只能取單一排序的數據。所以這里可以換成 rank() over()和dense_rank() over()來進行編號:(rank() over()和dense_rank() over()的區別如圖)

sum() over(),first_value() over()和last_value() over()的使用

sum() over()分組求和

first_value() over()求分組第一條

last_value() over()求分組最后一條

其中用row_number() over()取編號第一條的也可以實現first_value() over()的效果

 

  1.  
    SELECT DISTINCT *
  2.  
    FROM (SELECT T1.MI_ID,
  3.  
    T3.I_IDENTITY_CARD,
  4.  
    SUM(NVL(T2.IS_VISHEARTPROMEMBER, 0)) OVER(PARTITION BY T3.I_IDENTITY_CARD) PRO_NUM,
  5.  
    SUM(NVL(T2.IS_VISHEARTEXPMEMBER, 0)) OVER(PARTITION BY T3.I_IDENTITY_CARD) EXP_NUM,
  6.  
    SUM(NVL(T2.IS_VISHEARTPOLMEMBER, 0)) OVER(PARTITION BY T3.I_IDENTITY_CARD) POL_NUM,
  7.  
    T1.CREATE_TIME,
  8.  
    FIRST_VALUE(T2.CREATE_DATE) OVER(PARTITION BY T3.I_IDENTITY_CARD ORDER BY T2.CREATE_DATE DESC) FIRST_CREATE_DATE
  9.  
    FROM T_ZZ_PETITIONERS T1
  10.  
    LEFT JOIN T_ZZ_VISIT_RECORD T2
  11.  
    ON T1.CI_RS_ID = T2.CI_RS_ID
  12.  
    AND T2.STATUS != '003'
  13.  
    LEFT JOIN T_DC_CI_RS_TOP T3
  14.  
    ON T1.CI_RS_ID = T3.CI_RS_ID
  15.  
    AND T3.STATUS = '1'
  16.  
    WHERE T1.IS_ADD_HEARTPROTECT = '1'
  17.  
    AND T1.STATUS = '1') C
  18.  
    ORDER BY C.CREATE_TIME DESC


 

 

  1.  
    SELECT *
  2.  
    FROM (SELECT T1.MI_ID,
  3.  
    T3.I_IDENTITY_CARD,
  4.  
    SUM(NVL(T2.IS_VISHEARTPROMEMBER, 0)) OVER(PARTITION BY T3.I_IDENTITY_CARD) PRO_NUM,
  5.  
    SUM(NVL(T2.IS_VISHEARTEXPMEMBER, 0)) OVER(PARTITION BY T3.I_IDENTITY_CARD) EXP_NUM,
  6.  
    SUM(NVL(T2.IS_VISHEARTPOLMEMBER, 0)) OVER(PARTITION BY T3.I_IDENTITY_CARD) POL_NUM,
  7.  
    T1.CREATE_TIME,
  8.  
    ROW_NUMBER() OVER(PARTITION BY T3.I_IDENTITY_CARD ORDER BY T2.CREATE_DATE DESC) RNO
  9.  
    FROM T_ZZ_PETITIONERS T1
  10.  
    LEFT JOIN T_ZZ_VISIT_RECORD T2
  11.  
    ON T1.CI_RS_ID = T2.CI_RS_ID
  12.  
    AND T2.STATUS != '003'
  13.  
    LEFT JOIN T_DC_CI_RS_TOP T3
  14.  
    ON T1.CI_RS_ID = T3.CI_RS_ID
  15.  
    LEFT JOIN T_DC_GRID T4
  16.  
    ON T1.REGION_CODE = T4.INFO_ORG_CODE
  17.  
    WHERE T1.IS_ADD_HEARTPROTECT = '1'
  18.  
    AND T1.STATUS = '1'
  19.  
    AND T3.STATUS = '1'
  20.  
    AND T4.STATUS = '001') C
  21.  
    WHERE C.RNO = 1
  22.  
    ORDER BY C.CREATE_TIME DESC


 

ignore nulls:過濾掉空值

 

常用的分析函數如下所列:

row_number() over(partition by ... order by ...)
rank() over(partition by ... order by ...)
dense_rank() over(partition by ... order by ...)
count() over(partition by ... order by ...)
max() over(partition by ... order by ...)
min() over(partition by ... order by ...)
sum() over(partition by ... order by ...)
avg() over(partition by ... order by ...)
first_value() over(partition by ... order by ...)
last_value() over(partition by ... order by ...)
lag() over(partition by ... order by ...)
lead() over(partition by ... order by ...)

--------------------- 作者:East_MrChiu 來源:CSDN 原文:https://blog.csdn.net/east_mrchiu/article/details/70183428?utm_source=copy 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM