oracle的sql查詢分析函式-高階部分-分析函授over()子句
oracle的分析函式,應該是有一個格式的
function(argu1,argu2...)
over(partition by
order by
windowing-clause)
這是一個完整的分析函式的格式。
我之前用的分析函式,實際是省略了後面的over部分,也就是高階部分。
over分為3個部分:分組子句,partition by,這是指定對整體分析資料的分組依據;排序子句,order by,也就是對每個分組內的資料進行排序,同時也是一個預設的windowing函式;開窗子句,windowing-clause,這是一個資料視窗確定子句。
一個一個說明:
1、分組子句,partition by,這個分組部分,有點類似於group by子句,就是將整體資料,按照by後面提供的分組依據,按照依據值的不同,分成很多組,讓分析函式在每個組內工作,比如計算每個組的組內成員的sum值,這樣說,其實就是group by。
2、排序子句,order by,在order by之前,如果有分組子句,那麼就在每個分組內按照排序依據進行排序,如果沒有分組子句,那就是整個資料集進行排序。order by,是一個預設的開窗函式,也就是預設的windowing子句,其表示的意思就是:從分組或者整個資料集的第一行開始到當前行,所以排序子句,可以寫成這樣,order by 1,根據數字1進行排序,其實際就是不用排序,我只要確定每一個分組裡面有一個順序就可以了,不用確定按照那個欄位進行排序,這樣拿到的資料,估計是oracle按照內在的rowid給的排序。
3、視窗子句,windowing子句,這也是重點,也是難點。視窗子句,是指定每個分組內,分析函式要處理的資料行的範圍,也就是資料視窗,也就是說,用這個視窗子句,來確定在每個分組內,那些資料行要用分析函式來處理,比如sum函式,就是每個分組內,那些資料行的數值加入到sum函式計算的範圍內。再強調一次,視窗子句,就是指定那些資料行進入分析函式。視窗子句,透過兩種方式來指定進行分析的資料行,1是range,數值範圍,2是rows,資料行的偏移量,就是當前行的前面幾行到當前行的後面幾行。
視窗子句,必須和排序子句一起使用,也就是必須跟在order by子句後面,這樣,同時也指定了視窗子句語句中計算的依據欄位是那個,也就是視窗子句,開始時前面的那個指定欄位。
視窗子句具體寫法:
當前行的前面行 preceding
當前行的後面行 following
rows和range的寫法一樣,只是標記不同
range between 1 proceding and 1 following
rows between 1 proceding and 1 following
寫法是一樣的,只是一個range,一個rows。但是意識差別很大。
order by name desc,age desc range between 1 proceding and 1 following,指的是當前行的age欄位的數值,加1和減1之間的範圍,比如當前行的age欄位數值是3,那麼這個視窗指定的範圍應該是2到4,這樣說,也就是當前行的分析函式,要計算這個分組裡面,age欄位在2和4之間的資料行。而且,視窗子句的依據欄位,可以是日期,但是寫法不一樣,要這樣寫,range between interval '2' day proceding and interval '2' day following,這樣就是計算當前行的日期欄位的前兩天和後兩天之間的範圍,也就是5天,也就是當前天加上前兩天再加上後兩天。
order by name desc,age desc rows between 1 proceding and 1 following
是指,當前行的前面一行和後面一行之間的。注意這裡的兩個1,實際是指定了偏移量,也可以用其他寫法:
(1)、rows between UNBOUNDED proceding and UNBOUNDED following :UNBOUNDED PRECEDING:從當前分組的每一行開始到最後一行
(2)、rows between UNBOUNDED proceding and CURRENT ROW :CURRENT ROW:從當前分組的每一行開始,到當前行(並結束)
(3)、rows between CURRENT ROW and UNBOUNDED following :CURRENT ROW:從當前分組的當前行開始,到最後一行(並結束)
從上面的表述,可以看出,windowing子句,是最複雜的,要是覺得煩的,也可以不這樣算,可以用pl方式來做,只是需要一張臨時表而已,相對來說,可能PL方式更為複雜一些。
over函式,實際,就是給分析函式,確定分組,確定計算範圍的一個函式,是分析函式的附加部件。
加上over函式,可以完成一些超級複雜的計算要求。
下面我舉一個例子:
票據管理
表1,是每個票據的票面記錄,比如票據號,出票人,金額等,一個票據對應一個記錄。
表2,是每個票據的詳細記錄,比如每個票據內包含了那些商品,記錄商品的程式碼,數量,金額等。
題目1:我有個商品,程式碼是AB,要求計算出上個月出售這個商品(AB)的票據和票據總量比率,也就是佔比。
表1和表2,是一對多的關係,表1和表2,交叉配對,加入條件:表2程式碼=AB,這時候,還是一對多的關係,很難得出表1中的唯一記錄,就是,等到的表1記錄,表1.*這樣的寫法,得到的是很多重複項,可能有人想到distinct的寫法,如果票據的唯一依據是多個欄位,那麼很難用distinct來做,那麼我們就用over函式來做。
想法:
表1和表2的卡迪爾乘積,加上表2程式碼=AB的條件,表1.*得到的記錄,是很多的重複項,但是按照原定設計,表1裡面應該有一個唯一的依據欄位,也就是PK欄位,而且肯定是2個欄位以上,或者多個欄位,那麼我們就以表1的PK欄位,為partition by的分組依據,也就是partition by 表1.PK欄位1,表1.PK欄位2,這樣,表1.*得到的重複項,重複的資料行,就被分組到同一分組內,然後隨便用order by排序一下,用row_number給出一個序號,然後在外面一層的sql中,指定序號=1,這樣就直接所有重複項全部去除掉了。
實際:
select * from (select row_number()over(partition by a.PK欄位1,a.PK欄位2 order by 1) as item_rows,a.* from 表1 a,表2 b where a.no=b.no and b.code='AB') where item_rows=1;
我再做一個更復雜,同時也更為符合實際的需求。
題目2:要求查詢上個月購買了特定商品的顧客,佔比情況,要求統計出特定商品,特定商品是全部商品的佔比。
題目再說明:計算出,購買了商品AB的顧客佔比,這個簡單,但是我要求,不是單單一個商品AB,我要求一次性統計出,所有商品,商品A購買的顧客佔比,商品B購買的顧客佔比。
想法:
還是從表1和表2的卡迪爾乘積開始,只是和上面的過程不同,上面的分組依據是表1,現在我們以表2為分組依據,我們以表2中的商品程式碼為分組依據,這樣每個分組內,同樣有表1.*的資料,然後將表1.*的資料進行排序,同樣的操作,但是得到的結果不一樣。
實際:
function(argu1,argu2...)
over(partition by
order by
windowing-clause)
這是一個完整的分析函式的格式。
我之前用的分析函式,實際是省略了後面的over部分,也就是高階部分。
over分為3個部分:分組子句,partition by,這是指定對整體分析資料的分組依據;排序子句,order by,也就是對每個分組內的資料進行排序,同時也是一個預設的windowing函式;開窗子句,windowing-clause,這是一個資料視窗確定子句。
一個一個說明:
1、分組子句,partition by,這個分組部分,有點類似於group by子句,就是將整體資料,按照by後面提供的分組依據,按照依據值的不同,分成很多組,讓分析函式在每個組內工作,比如計算每個組的組內成員的sum值,這樣說,其實就是group by。
2、排序子句,order by,在order by之前,如果有分組子句,那麼就在每個分組內按照排序依據進行排序,如果沒有分組子句,那就是整個資料集進行排序。order by,是一個預設的開窗函式,也就是預設的windowing子句,其表示的意思就是:從分組或者整個資料集的第一行開始到當前行,所以排序子句,可以寫成這樣,order by 1,根據數字1進行排序,其實際就是不用排序,我只要確定每一個分組裡面有一個順序就可以了,不用確定按照那個欄位進行排序,這樣拿到的資料,估計是oracle按照內在的rowid給的排序。
3、視窗子句,windowing子句,這也是重點,也是難點。視窗子句,是指定每個分組內,分析函式要處理的資料行的範圍,也就是資料視窗,也就是說,用這個視窗子句,來確定在每個分組內,那些資料行要用分析函式來處理,比如sum函式,就是每個分組內,那些資料行的數值加入到sum函式計算的範圍內。再強調一次,視窗子句,就是指定那些資料行進入分析函式。視窗子句,透過兩種方式來指定進行分析的資料行,1是range,數值範圍,2是rows,資料行的偏移量,就是當前行的前面幾行到當前行的後面幾行。
視窗子句,必須和排序子句一起使用,也就是必須跟在order by子句後面,這樣,同時也指定了視窗子句語句中計算的依據欄位是那個,也就是視窗子句,開始時前面的那個指定欄位。
視窗子句具體寫法:
當前行的前面行 preceding
當前行的後面行 following
rows和range的寫法一樣,只是標記不同
range between 1 proceding and 1 following
rows between 1 proceding and 1 following
寫法是一樣的,只是一個range,一個rows。但是意識差別很大。
order by name desc,age desc range between 1 proceding and 1 following,指的是當前行的age欄位的數值,加1和減1之間的範圍,比如當前行的age欄位數值是3,那麼這個視窗指定的範圍應該是2到4,這樣說,也就是當前行的分析函式,要計算這個分組裡面,age欄位在2和4之間的資料行。而且,視窗子句的依據欄位,可以是日期,但是寫法不一樣,要這樣寫,range between interval '2' day proceding and interval '2' day following,這樣就是計算當前行的日期欄位的前兩天和後兩天之間的範圍,也就是5天,也就是當前天加上前兩天再加上後兩天。
order by name desc,age desc rows between 1 proceding and 1 following
是指,當前行的前面一行和後面一行之間的。注意這裡的兩個1,實際是指定了偏移量,也可以用其他寫法:
(1)、rows between UNBOUNDED proceding and UNBOUNDED following :UNBOUNDED PRECEDING:從當前分組的每一行開始到最後一行
(2)、rows between UNBOUNDED proceding and CURRENT ROW :CURRENT ROW:從當前分組的每一行開始,到當前行(並結束)
(3)、rows between CURRENT ROW and UNBOUNDED following :CURRENT ROW:從當前分組的當前行開始,到最後一行(並結束)
從上面的表述,可以看出,windowing子句,是最複雜的,要是覺得煩的,也可以不這樣算,可以用pl方式來做,只是需要一張臨時表而已,相對來說,可能PL方式更為複雜一些。
over函式,實際,就是給分析函式,確定分組,確定計算範圍的一個函式,是分析函式的附加部件。
加上over函式,可以完成一些超級複雜的計算要求。
下面我舉一個例子:
票據管理
表1,是每個票據的票面記錄,比如票據號,出票人,金額等,一個票據對應一個記錄。
表2,是每個票據的詳細記錄,比如每個票據內包含了那些商品,記錄商品的程式碼,數量,金額等。
題目1:我有個商品,程式碼是AB,要求計算出上個月出售這個商品(AB)的票據和票據總量比率,也就是佔比。
表1和表2,是一對多的關係,表1和表2,交叉配對,加入條件:表2程式碼=AB,這時候,還是一對多的關係,很難得出表1中的唯一記錄,就是,等到的表1記錄,表1.*這樣的寫法,得到的是很多重複項,可能有人想到distinct的寫法,如果票據的唯一依據是多個欄位,那麼很難用distinct來做,那麼我們就用over函式來做。
想法:
表1和表2的卡迪爾乘積,加上表2程式碼=AB的條件,表1.*得到的記錄,是很多的重複項,但是按照原定設計,表1裡面應該有一個唯一的依據欄位,也就是PK欄位,而且肯定是2個欄位以上,或者多個欄位,那麼我們就以表1的PK欄位,為partition by的分組依據,也就是partition by 表1.PK欄位1,表1.PK欄位2,這樣,表1.*得到的重複項,重複的資料行,就被分組到同一分組內,然後隨便用order by排序一下,用row_number給出一個序號,然後在外面一層的sql中,指定序號=1,這樣就直接所有重複項全部去除掉了。
實際:
select * from (select row_number()over(partition by a.PK欄位1,a.PK欄位2 order by 1) as item_rows,a.* from 表1 a,表2 b where a.no=b.no and b.code='AB') where item_rows=1;
我再做一個更復雜,同時也更為符合實際的需求。
題目2:要求查詢上個月購買了特定商品的顧客,佔比情況,要求統計出特定商品,特定商品是全部商品的佔比。
題目再說明:計算出,購買了商品AB的顧客佔比,這個簡單,但是我要求,不是單單一個商品AB,我要求一次性統計出,所有商品,商品A購買的顧客佔比,商品B購買的顧客佔比。
想法:
還是從表1和表2的卡迪爾乘積開始,只是和上面的過程不同,上面的分組依據是表1,現在我們以表2為分組依據,我們以表2中的商品程式碼為分組依據,這樣每個分組內,同樣有表1.*的資料,然後將表1.*的資料進行排序,同樣的操作,但是得到的結果不一樣。
實際:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9606200/viewspace-1816189/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle分析函式之開窗函式over()詳解Oracle函式
- SQL高階查詢SQL
- openGauss 高階分析函式支援函式
- 【SQL】Lag/Rank/Over視窗函式揭秘,資料分析之旅SQL函式
- oracle 高階函式Oracle函式
- 「Oracle」Oracle高階查詢介紹Oracle
- sql-server高階查詢SQLServer
- SQL查詢中用到的函式SQL函式
- 15、Oracle中的高階子查詢Oracle
- Oracle分析函式與視窗函式Oracle函式
- SQL語言基礎(高階查詢)SQL
- ORACLE分析函式手冊(轉)Oracle函式
- oracle學習筆記(十一) 高階查詢Oracle筆記
- Oracle查詢錯誤分析:ORA-01791:不是SELECTed表示式Oracle
- 高階查詢
- Mysql 資料庫 -------- SQL語句進階查詢 ------- 前部分MySql資料庫
- count函式與order by子句一起查詢時報錯處理函式
- ORACLE分析函式手冊二(轉)Oracle函式
- oracle資料庫常用分析函式與聚合函式的用法Oracle資料庫函式
- Python 函式進階-高階函式Python函式
- SQL server資料庫with as子句與遞迴查詢的實現SQLServer資料庫遞迴
- SQL查詢語句 (Oracle)SQLOracle
- ❖ MongoDB 高階查詢MongoDB
- Mongodb高階查詢MongoDB
- sql(oracle)資料處理實用總結開窗函式(over partition)使用SQLOracle函式
- 從Oracle 11.2.0.4 BUG到Oracle子查詢展開分析Oracle
- 高階函式函式
- SQL SERVER死鎖查詢,死鎖分析,解鎖,查詢佔用SQLServer
- 高階函式的使用函式
- Kotlin——高階篇(二):高階函式詳解與標準的高階函式使用Kotlin函式
- 從高階函式--->高階元件函式元件
- Oracle報performing DMLDDL operation over object in bin案例分析OracleORMObject
- (48)逆向分析 KiFastCallEntry 函式填充 _KTRAP_FRAME 部分AST函式
- Kotlin 函式6 - 高階函式Kotlin函式
- 資料庫高階查詢之子查詢資料庫
- SQL Server資料庫————模糊查詢和聚合函式SQLServer資料庫函式
- 使用SQL以及函式等做資料分析SQL函式
- Kotlin高階函式Kotlin函式
- python高階函式Python函式