亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Oracle > 正文

Oracle開發之分析函數(Top/Bottom N、First/Last、NTile)

2024-08-29 13:59:04
字體:
來源:轉載
供稿:網友

一、帶空值的排列:

在前面《Oracle開發之分析函數(Rank、Dense_rank、row_number)》一文中,我們已經知道了如何為一批記錄進行全排列、分組排列。假如被排列的數據中含有空值呢?

 

復制代碼 代碼如下:
SQL> select region_id, customer_id,
         sum(customer_sales) cust_sales,
         sum(sum(customer_sales)) over(partition by region_id) ran_total,
         rank() over(partition by region_id
                  order by sum(customer_sales) desc) rank
    from user_order
   group by region_id, customer_id;

 

 REGION_ID CUSTOMER_ID CUST_SALES  RAN_TOTAL       RANK
---------- ----------- ---------- ---------- ----------
        10          31                    6238901          1
        10          26    1808949    6238901          2
        10          27    1322747    6238901          3
        10          30    1216858    6238901          4
        10          28     986964    6238901          5
        10          29     903383    6238901          6

我們看到這里有一條記錄的CUST_TOTAL字段值為NULL,但居然排在第一名了!顯然這不符合情理。所以我們重新調整完善一下我們的排名策略,看看下面的語句:

 

復制代碼 代碼如下:
SQL> select region_id, customer_id,
         sum(customer_sales) cust_total,
         sum(sum(customer_sales)) over(partition by region_id) reg_total,
         rank() over(partition by region_id 
                        order by sum(customer_sales) desc NULLS LAST) rank
        from user_order
       group by region_id, customer_id;

 

 REGION_ID CUSTOMER_ID CUST_TOTAL  REG_TOTAL       RANK
---------- ----------- ---------- ---------- ----------
        10          26    1808949     6238901           1
        10          27    1322747    6238901           2
        10          30    1216858    6238901           3
        10          28     986964     6238901           4
        10          29     903383     6238901           5
        10          31     6238901                           6

綠色高亮處,NULLS LAST/FIRST告訴Oracle讓空值排名最后后第一。

注意是NULLS,不是NULL。

二、Top/Bottom N查詢:

在日常的工作生產中,我們經常碰到這樣的查詢:找出排名前5位的訂單客戶、找出排名前10位的銷售人員等等?,F在這個對我們來說已經是很簡單的問題了。下面我們用一個實際的例子來演示:

【1】找出所有訂單總額排名前3的大客戶:

 

復制代碼 代碼如下:
SQL> select *
  from (select region_id,
               customer_id,
               sum(customer_sales) cust_total,
               rank() over(order by sum(customer_sales) desc NULLS LAST) rank
         from user_order
         group by region_id, customer_id)
  where rank <= 3;

 

 REGION_ID CUSTOMER_ID CUST_TOTAL       RANK
---------- ----------- ---------- ----------
         9          25    2232703          1
         8          17    1944281          2
         7          14    1929774          3

SQL>

【2】找出每個區域訂單總額排名前3的大客戶:

 

復制代碼 代碼如下:
SQL> select *
    from (select region_id,
                 customer_id,
                 sum(customer_sales) cust_total,
                 sum(sum(customer_sales)) over(partition by region_id) reg_total,
                 rank() over(partition by region_id
                                order by sum(customer_sales) desc NULLS LAST) rank
            from user_order
           group by region_id, customer_id)
   where rank <= 3;

 

 REGION_ID CUSTOMER_ID CUST_TOTAL  REG_TOTAL       RANK
---------- ----------- ---------- ---------- ----------
         5           4    1878275    5585641          1
         5           2    1224992    5585641          2
         5           5    1169926    5585641          3
         6           6    1788836    6307766          1
         6           9    1208959    6307766          2
         6          10    1196748    6307766          3
         7          14    1929774    6868495          1
         7          13    1310434    6868495          2
         7          15    1255591    6868495          3
         8          17    1944281    6854731          1
         8          20    1413722    6854731          2
         8          18    1253840    6854731          3
         9          25    2232703    6739374          1
         9          23    1224992    6739374          2
         9          24    1224992    6739374          2
        10          26    1808949    6238901          1
        10          27    1322747    6238901          2
        10          30    1216858    6238901          3

18 rows selected.

三、First/Last排名查詢:

想象一下下面的情形:找出訂單總額最多、最少的客戶。按照前面我們學到的知識,這個至少需要2個查詢。第一個查詢按照訂單總額降序排列以期拿到第一名,第二個查詢按照訂單總額升序排列以期拿到最后一名。是不是很煩?因為Rank函數只告訴我們排名的結果,卻無法自動替我們從中篩選結果。

幸好Oracle為我們在排列函數之外提供了兩個額外的函數:first、last函數,專門用來解決這種問題。還是用實例說話:

 

復制代碼 代碼如下:
SQL> select min(customer_id)
         keep (dense_rank first order by sum(customer_sales) desc) first,
         min(customer_id)
         keep (dense_rank last order by sum(customer_sales) desc)
last
    from user_order
   group by customer_id;

 

     FIRST       LAST
---------- ----------
        31          1

這里有幾個看起來比較疑惑的地方:

①為什么這里要用min函數
②Keep這個東西是干什么的
③fist/last是干什么的
④dense_rank和dense_rank()有什么不同,能換成rank嗎?

首先解答一下第一個問題:min函數的作用是用于當存在多個First/Last情況下保證返回唯一的記錄。假如我們去掉會有什么樣的后果呢?

 

復制代碼 代碼如下:
SQL> select keep (dense_rank first order by sum(customer_sales) desc) first,
             keep (dense_rank last order by sum(customer_sales) desc) last
    from user_order
   group by customer_id;
select keep (dense_rank first order by sum(customer_sales) desc) first,
                        *

 

ERROR at line 1:
ORA-00907: missing right parenthesis

接下來看看第2個問題:keep是干什么用的?從上面的結果我們已經知道Oracle對排名的結果只“保留”2條數據,這就是keep的作用。告訴Oracle只保留符合keep條件的記錄。

那么什么才是符合條件的記錄呢?這就是第3個問題了。dense_rank是告訴Oracle排列的策略,first/last則告訴最終篩選的條件。

第4個問題:如果我們把dense_rank換成rank呢?

 

復制代碼 代碼如下:
SQL> select min(region_id)
          keep(rank first order by sum(customer_sales) desc) first,
         min(region_id)
          keep(rank last order by sum(customer_sales) desc) last
    from user_order
   group by region_id;
select min(region_id)
*

 

ERROR at line 1:
ORA-02000: missing DENSE_RANK

四、按層次查詢:

現在我們已經見識了如何通過Oracle的分析函數來獲取Top/Bottom N,第一個,最后一個記錄。有時我們會收到類似下面這樣的需求:找出訂單總額排名前1/5的客戶。

很熟悉是不?我們馬上會想到第二點中提到的方法,可是rank函數只為我們做好了排名,并不知道每個排名在總排名中的相對位置,這時候就引入了另外一個分析函數NTile,下面我們就以上面的需求為例來講解一下:

 

復制代碼 代碼如下:
SQL> select region_id,
         customer_id,
         ntile(5) over(order by sum(customer_sales) desc) til
    from user_order
   group by region_id, customer_id;

 

 REGION_ID CUSTOMER_ID       TILE
---------- ----------- ----------
        10          31          1
         9          25           1
        10          26          1
         6           6            1        
         8          18           2
         5           2            2
         9          23           3
         6           9            3
         7          11           3
         5           3            4
         6           8            4
         8          16           4
         6           7            5
        10          29          5
         5           1            5

Ntil函數為各個記錄在記錄集中的排名計算比例,我們看到所有的記錄被分成5個等級,那么假如我們只需要前1/5的記錄則只需要截取TILE的值為1的記錄就可以了。假如我們需要排名前25%的記錄(也就是1/4)那么我們只需要設置ntile(4)就可以了。

以上就是Oracle中前幾名、后幾名、最多、最少以及按層次查詢的全部內容,希望能給大家一個參考,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到oracle教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品久久久久久中文字幕一区奶水| 青青草成人在线| 日韩在线观看免费高清| 国产一区二区三区直播精品电影| 久久久久久久久久久av| 日韩免费在线电影| 51精品在线观看| 2018国产精品视频| 国产亚洲综合久久| 国产精品久久久久久影视| 2019中文字幕在线免费观看| 亚洲一区二区中文字幕| 中文综合在线观看| 国产一区二区激情| 正在播放欧美视频| 日本高清不卡的在线| 亚洲成色www8888| 九九久久久久久久久激情| 91中文精品字幕在线视频| 日本不卡视频在线播放| 欧美日韩中文字幕在线视频| 91精品国产综合久久久久久蜜臀| 国产精品第七十二页| 8x海外华人永久免费日韩内陆视频| 操日韩av在线电影| 国产不卡av在线| 国产精品黄色av| 欧美人与性动交a欧美精品| 91最新在线免费观看| 国产高清视频一区三区| 夜夜狂射影院欧美极品| 欧美日韩在线一区| 久久久久久亚洲精品不卡| 成人网在线免费看| 亚洲久久久久久久久久久| 97人洗澡人人免费公开视频碰碰碰| 两个人的视频www国产精品| 538国产精品视频一区二区| 成人免费视频xnxx.com| 日韩欧美亚洲国产一区| 久久电影一区二区| 亚洲国产古装精品网站| 欧美成人精品影院| 欧美老妇交乱视频| 欧美精品videosex性欧美| 中文欧美在线视频| 国产91在线播放精品91| 一区二区成人av| 97婷婷大伊香蕉精品视频| 久久精品人人做人人爽| 亚洲最新av在线网站| 另类美女黄大片| 日韩成人中文字幕| 亚洲人精选亚洲人成在线| 欧美猛少妇色xxxxx| 中文字幕欧美日韩精品| 日韩精品久久久久| 欧美日韩国产一区二区三区| 亚洲欧洲视频在线| 91精品久久久久久久久久入口| 全球成人中文在线| 91国产高清在线| 日韩美女视频在线观看| 亚洲欧洲午夜一线一品| 亚洲已满18点击进入在线看片| 亚洲欧美自拍一区| 黄色成人av网| 国产精品久久久久久久久久久久| 久久亚洲私人国产精品va| 成人妇女免费播放久久久| 日韩精品欧美激情| 久久成人在线视频| 欧美另类99xxxxx| 最近中文字幕日韩精品| 欧美激情网站在线观看| 狠狠干狠狠久久| 日韩亚洲欧美中文高清在线| 96精品久久久久中文字幕| 国产精品爱久久久久久久| 久久久久久久久亚洲| 欧美www视频在线观看| 亚洲午夜小视频| 日韩www在线| 日本亚洲欧洲色α| 伊人伊人伊人久久| 欧美在线免费视频| 国产精品九九九| www.欧美三级电影.com| 38少妇精品导航| 中文字幕欧美日韩va免费视频| 一区二区在线视频播放| 精品国产一区二区三区久久狼黑人| 欧美日韩免费在线| 国产精品久久99久久| 成人福利网站在线观看| 中文字幕v亚洲ⅴv天堂| 久久精品99久久香蕉国产色戒| 久久久av一区| 亚洲国产成人爱av在线播放| 久久久久久亚洲精品中文字幕| 97在线日本国产| 国产a级全部精品| 久久精品视频亚洲| 欧美成人免费全部观看天天性色| 韩剧1988在线观看免费完整版| 国产精品欧美在线| 亚洲加勒比久久88色综合| 国产福利精品在线| 久久久久久999| 色综合视频一区中文字幕| 欧美在线国产精品| 永久免费看mv网站入口亚洲| 97香蕉久久超级碰碰高清版| 久久亚洲精品小早川怜子66| 亚洲毛片在线观看| 91国产精品电影| 91精品国产乱码久久久久久久久| 欧美日产国产成人免费图片| 精品美女国产在线| 国产亚洲精品久久久优势| 精品久久久久久久久久国产| 国产99久久精品一区二区永久免费| 欧美xxxwww| 国产精品久久久久久久久免费| 亚洲第一网站免费视频| 国产精品自产拍在线观| 欧美激情视频网址| 欧美体内谢she精2性欧美| 色老头一区二区三区在线观看| 国产欧美精品在线| 亚洲精品一区av在线播放| 久久成人在线视频| 精品性高朝久久久久久久| 91亚洲国产精品| 成人av.网址在线网站| 一级做a爰片久久毛片美女图片| 欧美电影免费看| 色妞一区二区三区| 日韩av网站电影| 日韩福利在线播放| 91av成人在线| 成人动漫网站在线观看| 伊人伊成久久人综合网小说| 亚洲国产精品系列| 高清一区二区三区四区五区| 久久久久久久久久久国产| 成人精品视频在线| 亚洲精品理论电影| 草民午夜欧美限制a级福利片| 国产精品91在线| 精品夜色国产国偷在线| 亚洲va久久久噜噜噜久久天堂| 91日韩在线播放| 欧美高清视频一区二区| 日韩欧美亚洲范冰冰与中字| 日韩在线视频二区| 欧美久久精品午夜青青大伊人| 亚洲一区二区日本| 亚洲国产私拍精品国模在线观看| 国产一区二区三区在线看| 亚洲欧洲在线观看| 5278欧美一区二区三区| 欧美成人精品在线播放| 欧美性猛交xxxx久久久|