OVER(PARTITION BY)函數介紹

来源:http://www.cnblogs.com/lcngu/archive/2016/03/31/5335170.html
-Advertisement-
Play Games

問題場景 最近在項目中遇到了對每一個類型進行求和並且求該類型所占的比例,當時考慮求出每種類型的和,併在java中分別對每一種類型的和與總和相除求出所占比例。後來,想到這樣有點麻煩,並且項目中持久層使用的是iBatis框架,所有考慮從SQL方面進行入手來簡化這個問題。 後來SQL的解決方法就為: 看到 ...


  • 問題場景  

  最近在項目中遇到了對每一個類型進行求和並且求該類型所占的比例,當時考慮求出每種類型的和,併在java中分別對每一種類型的和與總和相除求出所占比例。後來,想到這樣有點麻煩,並且項目中持久層使用的是iBatis框架,所有考慮從SQL方面進行入手來簡化這個問題。

  後來SQL的解決方法就為:

1 SELECT T.CHANNEL AS PATTERN,
2        COUNT(T.TRANSACTIONKEY) AS T_COUNT,
3        SUM(T.AMT) AS T_AMT,
4        ROUND(100 * SUM(T.AMT) / SUM(SUM(T.AMT)) OVER(PARTITION BY 1), 2) AS AMT_PERCENT,
5        ROUND(100 * COUNT(T.TRANSACTIONKEY) / SUM(COUNT(T.TRANSACTIONKEY)) OVER(PARTITION BY 1),2) AS COUNT_PERCENT
6   FROM XX(表名) T
7  WHERE T.PARTY_ID = '100579050'
8  GROUP BY T.CHANNEL

  看到這裡自己很佩服SQL的強大,於是刨根問底,深入研究了一番Oracel的OVER(PARTITION BY)函數。

  • 簡介

  開窗函數,Oracle從8.1.6開始提供分析函數,分析函數用於計算基於組的某種聚合值,它和聚合函數的不同之處是:對於每個組返回多行,而聚合函數對於每個組只返回一行。

  開窗函數指定了分析函數工作的數據視窗大小,這個數據視窗大小可能會隨著行的變化而變化。

  下麵的測試用例數據語句如下: 

 1 create table T2_TEMP(
 2     NAME varchar2(10) primary key,
 3     CLASS varchar2(10),
 4     SROCE NUMBER 
 5 )
 6 
 7 insert into T2_TEMP (NAME, CLASS, SROCE)
 8 values ('cfe', '2', 74);
 9 
10 insert into T2_TEMP (NAME, CLASS, SROCE)
11 values ('dss', '1', 95);
12 
13 insert into T2_TEMP (NAME, CLASS, SROCE)
14 values ('ffd', '1', 95);
15 
16 insert into T2_TEMP (NAME, CLASS, SROCE)
17 values ('fda', '1', 80);
18 
19 insert into T2_TEMP (NAME, CLASS, SROCE)
20 values ('gds', '2', 92);
21 
22 insert into T2_TEMP (NAME, CLASS, SROCE)
23 values ('gf', '3', 99);
24 
25 insert into T2_TEMP (NAME, CLASS, SROCE)
26 values ('ddd', '3', 99);
27 
28 insert into T2_TEMP (NAME, CLASS, SROCE)
29 values ('adf', '3', 45);
30 
31 insert into T2_TEMP (NAME, CLASS, SROCE)
32 values ('asdf', '3', 55);
33 
34 insert into T2_TEMP (NAME, CLASS, SROCE)
35 values ('3dd', '3', 78);
View Code

  1、over函數的寫法:

  over(partition by class order by sroce) 按照sroce排序進行累計,order by是個預設的開窗函數,按照class分區。

  2、開窗的視窗範圍:

  over(order by sroce range between 5 preceding and 5 following):視窗範圍為當前行數據幅度減5加5後的範圍內的。

  over(order by sroce rows between 5 preceding and 5 following):視窗範圍為當前行前後各移動5行。

  3、與over()函數結合的函數的介紹

  (1)、查詢每個班的第一名的成績:如下 

1 SELECT * FROM (select t.name,t.class,t.sroce,rank() over(partition by t.class order by t.sroce desc) mm from T2_TEMP t) where mm = 1;

  結果為:

1 得到的結果是:
2 dss        1        95        1
3 ffd        1        95        1
4 gds        2        92        1
5 gf         3        99        1
6 ddd        3        99        1

  註意:在求第一名成績的時候,不能用row_number(),因為如果同班有兩個併列第一,row_number()只返回一個結果。

1 SELECT * FROM (select t.name,t.class,t.sroce,row_number() over(partition by t.class order by t.sroce desc) mm from T2_TEMP t) where mm = 1;

  結果為:

dss      1        95        1  
gfs      2        92        1
ddd      3        99        1 

  可以看出,本來第一名是兩個人的併列,結果只顯示了一個。

  (2)、rank()和dense_rank()可以將所有的都查找出來,rank可以將併列第一名的都查找出來;rank()和dense_rank()區別:rank()是跳躍排序,有兩個第二名時接下來就是第四名。

  求班級成績排名:

1 select t.name,t.class,t.sroce,rank() over(partition by t.class order by t.sroce desc) mm from T2_TEMP t;

  查詢結果:

dss        1        95        1
ffd        1        95        1
fda        1        80        3
gds        2        92        1
cfe        2        74        2
gf         3        99        1
ddd        3        99        1
3dd        3        78        3
asdf       3        55        4
adf        3        45        5

  dense_rank()l是連續排序,有兩個第二名時仍然跟著第三名

1 select t.name,t.class,t.sroce,dense_rank() over(partition by t.class order by t.sroce desc) mm from T2_TEMP t;

  查詢結果:

dss        1        95        1
ffd        1        95        1
fda        1        80        2 
gds        2        92        1
cfe        2        74        2
gf         3        99        1
ddd        3        99        1
3dd        3        78        2
asdf       3        55        3
adf        3        45        4

  3、sum()over()的使用

  根據班級進行分數求和

1 select t.name,t.class,t.sroce,sum(t.sroce) over(partition by t.class order by t.sroce desc) mm from T2_TEMP t;
dss        1        95        190  --由於兩個95都是第一名,所以累加時是兩個第一名的相加
ffd        1        95        190 
fda        1        80        270  --第一名加上第二名的
gds        2        92        92
cfe        2        74        166
gf         3        99        198
ddd        3        99        198
3dd        3        78        276
asdf       3        55        331
adf        3        45        376

  4、first_value() over()和last_value() over()的使用 

1 select t.name,t.class,t.sroce,first_value(t.sroce) over(partition by t.class order by t.sroce desc) mm from T2_TEMP t;
2 select t.name,t.class,t.sroce,last_value(t.sroce) over(partition by t.class order by t.sroce desc) mm from T2_TEMP t;

  分別求出第一個和最後一個成績。

  5、sum() over()的使用

1 select t.name,t.class,t.sroce,sum(t.sroce) over(partition by t.class order by t.sroce desc) mm from T2_TEMP t;

  求出班級的總分。

  下麵還有很多用法,就不一一列舉了,簡單介紹一下,和上面用法類似:

 

  count() over(partition by ... order by ...):求分組後的總數。
  max() over(partition by ... order by ...):求分組後的最大值。
  min() over(partition by ... order by ...):求分組後的最小值。
  avg() over(partition by ... order by ...):求分組後的平均值。
  lag() over(partition by ... order by ...):取出前n行數據。  

  lead() over(partition by ... order by ...):取出後n行數據。

  ratio_to_report() over(partition by ... order by ...):Ratio_to_report() 括弧中就是分子,over() 括弧中就是分母。

  percent_rank() over(partition by ... order by ...):

  6、over partition by與group by的區別:

  group by是對檢索結果的保留行進行單純分組,一般和聚合函數一起使用例如max、min、sum、avg、count等一塊用。partition by雖然也具有分組功能,但同時也具有其他的高級功能。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在iOS開發中,經常會在APP首頁看到多張圖片進行輪換。剛開始做的時候,感覺很麻煩,不是很好做,查閱資料後,我總結了一下,自己封裝了一個簡單的輪轉圖片庫; UIScrollView無限滑動 ,只需要三個View,左視圖,中視圖,右視圖。無論向左滑動,還是向右滑動,都顯示中間的一個View; ( _s ...
  • 動畫資源 一、分類: (一)、概要: 動畫資源 一、分類: 3.0以前,android支持兩種動畫模式,補間動畫(tween animation),幀動畫(frame animation),在android3.0中又引入了一個新的動畫系統:屬性動畫(property animation)。 這三種動 ...
  • 【瘋狂造輪子-iOS】JSON轉Model系列之一 本文轉載請註明出處 —— polobymulberry-博客園 1. 前言 之前一直看別人的源碼,雖然對自己提升比較大,但畢竟不是自己寫的,很容易遺忘。這段時間準備自己造一些輪子,主要目的還是為了提升自身實力,總不能一遇到問題就Google。 之前 ...
  • 如果手機沒有root,資料庫文件是無法查看到的,不方便調試。 最好的辦法是把資料庫寫進SD卡。 修改的地方有兩處: 1.在你的helper類中把資料庫文件名稱 DATABASE_NAME 由原來的一個文件名,修改成路徑的形式。 修改前:DATABASE_NAME = "demo.db" 修改後:DA ...
  • 這篇文章介紹的是一個簡單而又實用的小方法。 我想對於登陸時的一些效果大家應該都不會陌生。 今天就介紹一下,當開始輸入TextField文本時鍵盤彈出TextField伴隨鍵盤移動的實現。 先看一下演示效果 我們對TextFiel進行約束。約束內容如下⬇️ 約束結束後,我們需要做一個很重要的是,就是把 ...
  • CoreData資料庫遷移操作步驟,操作是基於Xcode7. 1.添加新的資料庫.選中當前資料庫版本:Editor->Add Model Verson,創建一個新的資料庫版本. 2.Command + N,創建一個映射模型.iOS->CoreData->Mapping Model->Next,選擇舊 ...
  • 《android註冊頁面》博客中main.xml代碼中每個組件定義的屬性有重覆的部分,為了避免繁瑣可以把各個組件重覆的屬性定義到一個文件中:res/values/style_test.xml源碼: <?xml version="1.0" encoding="utf-8"?><resources> < ...
  • 從昨天下午接到新任務,要採集一個法院網站得所有公告,大概是需要採集這個網站得所有公告列表裡得所有txt內容,txt文件裡邊是一件件赤裸裸得案件,記錄這案由,原告被告等相關屬性(不知道該叫什麼就稱之為屬性吧,汗),把這些文件放到本地某個目錄,並把一個案件作為一條數據放入資料庫中。本以為很輕鬆得用Jso ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...