用ORACLE分析函式實現行列轉換
摘 要 對資料庫中的資料用SQL實現行列轉換,不但需要編寫複雜的程式程式碼,還需要編寫儲存過程。若引入ORACLE中的分析函式則會使該過程簡便很多。首先找出表中所有關鍵字的屬性個數的最大值,設為n,其次為每個關鍵字新新增n列,並用分析函式查詢關鍵字的屬性所處列的位置,然後將每個關鍵字的多行屬性轉換成多列屬性,最後把生成的多個新列拼成一個串形成一列,從而實現行列轉換。
關鍵字 Oracle資料庫;分析函式;行列轉換
1 引言
分析函式的設計目的是為了解決諸如“累計計算”等問題。雖然大部分的問題都可以用PL/SQL解決,但是效能並不理想,首先查詢本身並不容易編寫,其次有些很難在SQL中直接做的查詢但實際上是很普通的操作,比如實現資料表中行列傳換。這樣的問題在SQL中做查詢就很困難。在分析函式出現以前,我們必須使用自聯查詢或者子查詢甚至複雜的儲存過程實現的語句,現在只要一條簡單的SQL語句就可以實現了,而且在執行效率方面也有相當大的提高。本文將以一個例項來描述如何採用分析函式實現資料中的行列互換。
2 原理
2.1 分析函式的格式及語法
分析函式是在一個記錄行分組的基礎上計算它們的總值。行的分組被稱視窗,並透過分析語句定義。對於每記錄行,定義了一個“滑動”視窗。該視窗確定“當前行”計算的範圍。視窗的大小可由各行的實際編號或由時間等邏輯間隔確定。
分析函式以如下形式開頭:
Analytic-Function(,,...)
OVER ()
(1)Analytic-Function:分析函式的名稱,Oracle10gR2帶的內建分析函式有多個,包括:AVG、CORR、COVAR_POP、COVAR_SAMP、COUNT、LAG、LAST、LEAD、MAX、MIN、RANK、SUM等;對於使用者自定義的分析函式,分析函式名稱需要滿足識別符號規則。
(2)Arguments:引數,分析函式通常有0到3個引數,引數可以是任何數字型別或是可以隱式轉換為數字型別的資料型別。對於使用者自定義的引數,可以根據實際情況使用。
(3)OVER:是分析函式就必須使用的關鍵字,對於既可作為聚集函式又可作為分析函式的函式,Oracle無法識別,必須用over來標識此函式為分析函式。
(4)Query-Partition-Clause:查詢分組子句,根據劃分表示式設定的規則,PARTITION BY將一個結果邏輯分成N個分組劃分表示式。分析函式獨立應用於各個分組,並在應用時重置。
(5)Order-By-Clause:(按…排序分組),是排序子句,根據一個或多個排序表示式對分組進行排序。
(6)Windowing-Clause視窗生成語句:視窗生成語句用以定義滑動或固定資料視窗,分析函式在分組內進行分析。該語句能夠對分組中任意定義的滑動或固定視窗進行計算。
2.2 例項原理介紹
本例項是將具有相同關鍵字的多條記錄中的某一不同列合併成一列,例如在一個臨時表中包含有使用者的編號、電話號碼、產品名稱、所在營業區以及相關業務名稱5個欄位,而每個使用者的業務可能有多項,這樣建立資料表將會造成冗餘,現在要想辦法將表中編號、電話號碼、產品名稱、所在營業區四個欄位相同的使用者的相關業務屬性合併成一列解決冗餘問題,使用SQL語句會比較困難,甚至需要一定的儲存過程。使用Orcale中的分析函式來實現這樣的行列轉換就比較簡單方便了。
3 例項
1)建立臨時表
Drop Table temp;
Create Table temp
(
num varchar2(15 Char),
name varchar2(20 Char),
sex varchar2(2 Char),
classes varchar2(30 Char),
course_name varchar2(50 Char)
);
Create Table temp
(
num varchar2(15 Char),
name varchar2(20 Char),
sex varchar2(2 Char),
classes varchar2(30 Char),
course_name varchar2(50 Char)
);
2)構造資料
insert into temp(num,name,sex,classes,course_name) values ('206211','王藝','男','06-1班','保險學');
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','保險學');
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','財務管理');
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','財務會計');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','電子商務');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','公共經濟學');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','公司理財');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','管理學原理');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','保險學');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','保險學');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','財務管理');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','財務會計');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','電子商務');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','公共經濟學');
insert into temp(num,name,sex,classes,course_name) values ('206215','楊伊琳','女','06-3班','環境管理學');
insert into temp(num,name,sex,classes,course_name) values ('206215','楊伊琳','女','06-3班','管理學原理');
insert into temp(num,name,sex,classes,course_name) values ('206215','楊伊琳','女','06-3班','商務談判');
insert into temp(num,name,sex,classes,course_name) values ('206216','李佳琪','男','06-2','土地估計');
Commit;
3)先查一下course_name最多的組合
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','保險學');
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','財務管理');
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','財務會計');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','電子商務');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','公共經濟學');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','公司理財');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','管理學原理');
insert into temp(num,name,sex,classes,course_name) values ('206213','陳雅詩','女','06-2','保險學');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','保險學');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','財務管理');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','財務會計');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','電子商務');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹陽','男','06-1','公共經濟學');
insert into temp(num,name,sex,classes,course_name) values ('206215','楊伊琳','女','06-3班','環境管理學');
insert into temp(num,name,sex,classes,course_name) values ('206215','楊伊琳','女','06-3班','管理學原理');
insert into temp(num,name,sex,classes,course_name) values ('206215','楊伊琳','女','06-3班','商務談判');
insert into temp(num,name,sex,classes,course_name) values ('206216','李佳琪','男','06-2','土地估計');
Commit;
3)先查一下course_name最多的組合
select max(count(course_name))
from temp
group by num,name,sex,classes;
from temp
group by num,name,sex,classes;
4) 列的位置
用分析函式中的row_number函式,在num,name,sex,classes相同的情況下course_name所處的列的位置(第幾列)。
row_number函式解釋:返回有序組中一行的偏移量,從而可用於按特定標準排序的行號。
select num,name,sex,classes,course_name,
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp;
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp;
5)把course_name的所有的行換成列
select num,name,sex,classes,
max(decode(rn,1,course_name,null)) course_name_1,
max(decode(rn,2,course_name,null)) course_name_2,
max(decode(rn,3,course_name,null)) course_name_3,
max(decode(rn,4,course_name,null)) course_name_4,
max(decode(rn,5,course_name,null)) course_name_5
from (select num,name,sex,classes,course_name,
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp)
group by num,name,sex,classes;
max(decode(rn,1,course_name,null)) course_name_1,
max(decode(rn,2,course_name,null)) course_name_2,
max(decode(rn,3,course_name,null)) course_name_3,
max(decode(rn,4,course_name,null)) course_name_4,
max(decode(rn,5,course_name,null)) course_name_5
from (select num,name,sex,classes,course_name,
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp)
group by num,name,sex,classes;
6)把轉換後的name拼成一個字串,放在一行
select num,name,sex,classes,
(max(decode(rn,1,course_name,null)) || max(decode(rn,2,',' || course_name,null)) || max(decode(rn,3,',' || course_name,null)) || max(decode(rn,4,',' || course_name,null)) ||
max(decode(rn,5,',' || course_name,null))) name
from (select num,name,sex,classes,course_name,
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp)
group by num,name,sex,classes;
(max(decode(rn,1,course_name,null)) || max(decode(rn,2,',' || course_name,null)) || max(decode(rn,3,',' || course_name,null)) || max(decode(rn,4,',' || course_name,null)) ||
max(decode(rn,5,',' || course_name,null))) name
from (select num,name,sex,classes,course_name,
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp)
group by num,name,sex,classes;
4 總結
本文中的程式能夠實現以下功能:①計算具有相同關鍵字的最多的組合;②根據分析函式查詢某一關鍵字所處的列的位置;③把需合併列的所有的行換成列;④把需要合併的某幾列拼成一個串。
分析函式除了擁有以上所介紹的功能,還能夠實現諸如求和、Top-N查詢、統計某個範圍的資料行視窗、交叉表查詢等功能。
(新疆師範大學 數理資訊學院,新疆 830054)
[@more@]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/658202/viewspace-1036990/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spark實現行列轉換pivot和unpivotSpark
- Oracle OCP(05):轉換函式Oracle函式
- Oracle行列轉換及pivot子句的用法Oracle
- ORACLE分析函式手冊(轉)Oracle函式
- 使用vue實現行列轉換的一種方法。Vue
- ORACLE分析函式手冊二(轉)Oracle函式
- Oracle分析函式之LEAD和LAG實際應用Oracle函式
- MySQL分析函式實現MySql函式
- mysql行列轉換詳解MySql
- Restcloud ETl實踐之資料行列轉換RESTCloud
- 用listagg函式分組實現列轉行函式
- Oracle分析函式與視窗函式Oracle函式
- 報表如何實現行列互換效果?
- 在報表中錄入資料時如何實現行列轉換
- oracle函式手冊(轉)Oracle函式
- 記錄一個行列轉換
- 函式匹配和實參型別轉換函式型別
- 實現二維陣列的行列互換陣列
- web 展現資料時如何實現行列互換Web
- SQL 如何實現動態的行列轉置SQL
- 8.轉換文字函式函式
- 神經網路啟用函式=生物轉換器?神經網路函式
- 如何實現隱式型別轉換型別
- Oracle分析函式之開窗函式over()詳解Oracle函式
- 呼叫函式實現兩個數交換函式
- Oracle實驗(02):轉換 & 轉譯Oracle
- oracle Forms Builder常用函式 (轉載)OracleORMUI函式
- 【函式】Oracle12c 列轉行函式使用listagg函式Oracle
- 用匯編實現add函式函式
- 用Java實現samza轉換成flinkJava
- 13、MySQL Case-MySQL分析函式實現MySql函式
- oracle資料隱式轉換規則Oracle
- oracle資料庫常用分析函式與聚合函式的用法Oracle資料庫函式
- GaussDB: db2->gaussdb 函式轉換DB2函式
- 一次ORACLE字元轉換分析過程Oracle字元
- python函式每日一講 - float函式型別轉換詳解Python函式型別
- 用Map+函式式介面來實現策略模式函式模式
- oracle 函式Oracle函式
- oracle or 函式Oracle函式