rank() over(partition)的使用


     有的時候會遇到這樣的問題,我們需要查詢一張表,而且要按照業務排序,比如我需要如下的結果:

    地區   日期    費用  產品編號   用戶編號

     290 201202 258 1              s1
     290 201202 200 1              s5
     290 201202 100 1              s100
     290 201202 90   2              s7
     290 201202 88   2              s9
     290 201202 10   2              s12。 

     領導讓我出一張報表,需要看到每一個業務的收費前三名是那些客戶。這個時候用rank() over(partition)是一個很不錯的選擇。

     我的測試表就像上面例子中的表一樣,不過數據稍微多一點點。給大家一個截圖:

     

      可以看到我每一個項目都有5條記錄,我只取前三,那么SQL如下:

      

SELECT A.AREA_ID, A.ACCT_MONTH, A.FEE, A.ITEM_ID, A.USER_ID
FROM (SELECT T.AREA_ID,
T.ACCT_MONTH,
T.FEE,
T.ITEM_ID,
T.USER_ID,
RANK() OVER(PARTITION BY T.ITEM_ID ORDER BY T.FEE DESC) RK
FROM TEST T) A
WHERE RK < 4;

       該語句執行的結果就是上述的情況了。

       一不做二不休,我順便查看一下該語句的執行計划好了。

       首先寫一下我的建表語句:

       

CREATE TABLE TEST
(
area_id NUMBER,
acct_month NUMBER,
fee NUMBER,
item_id NUMBER
)
PARTITION BY LIST(area_id)
(
PARTITION part_290 VALUES('290'),
PARTITION part_910 VALUES('910'),
PARTITION part_911 VALUES('911'),
partition part_912 values('912'),
partition part_913 values('913'),
partition part_914 values('914'),
partition part_915 values('915'),
partition part_916 values('916'),
partition part_917 values('917'),
partition part_919 values('919'),
partition part_default values(default)
)

      我按照地域進行了分區,其實也可以按照時間進行分區。explain一下plan:

       

      可以看到,只有10條記錄的表,COST卻高達4,不得不說采取這個辦法會極大地降低查詢的效率。但是業務上需要的話,rank() over確實是一個很好使的玩意兒。

      加兩條數據進去,順便測測分區表是否真的可以在沒有索引的情況下提高一點點效率。加了兩條數據,area_id是911,陝西省寶雞市的區號:0911。語句也稍微變動一下:

SELECT A.AREA_ID, A.ACCT_MONTH, A.FEE, A.ITEM_ID, A.USER_ID
FROM (SELECT T.AREA_ID,
T.ACCT_MONTH,
T.FEE,
T.ITEM_ID,
T.USER_ID,
RANK() OVER(PARTITION BY T.ITEM_ID ORDER BY T.FEE DESC) RK
FROM TEST T
WHERE t.area_id = 290) A
WHERE RK < 4;

      explain一下plan:

      

      發現雖然現在是12行數據,但是因為我只查詢西安市(290),所以在rows里仍舊只是10行,沒有新添加的寶雞市的2行。由此可見,在面對非常海量的數據存儲時,按照一定的條件建立分區,是十分有必要的。不過按照時間建立分區可能會稍微麻煩點,因為時間在不停的推進,多少年之后,你現在建立的分區就已經不可能再用了,就要添加新的分區進去,這也是一個挺討厭的事情。



      


免責聲明!

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



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