關(guān)于ORACLE中的DECODE
關(guān)于ORACLE中的DECODE- -
關(guān)于DECODE
DECODE是Oracle公司獨(dú)家提供的功能,它是一個(gè)功能很強(qiáng)的函數(shù)。它雖然不是SQL的標(biāo)準(zhǔn),但對(duì)于性能非常有用。到目前,其他的數(shù)據(jù)庫(kù)供應(yīng)商還不能提供類(lèi)似DECODE的功能,甚至有的數(shù)據(jù)庫(kù)的供應(yīng)商批評(píng)Oracle的SQL不標(biāo)準(zhǔn)。實(shí)際上,這種批評(píng)有些片面或不夠水平。就象有些馬車(chē)制造商抱怨亨利。福特的“馬車(chē)”不標(biāo)準(zhǔn)一樣。
1 DECODE 中的if-then-else邏輯
在邏輯編程中,經(jīng)常用到If – Then –Else 進(jìn)行邏輯判斷。在DECODE的語(yǔ)法中,實(shí)際上就是這樣的邏輯處理過(guò)程。它的語(yǔ)法如下:
DECODE(value, if1, then1, if2,then2, if3,then3, . . . else )
Value 代表某個(gè)表的任何類(lèi)型的任意列或一個(gè)通過(guò)計(jì)算所得的任何結(jié)果。當(dāng)每個(gè)value值被測(cè)試,如果value的值為if1,Decode 函數(shù)的結(jié)果是then1;如果value等于if2,Decode函數(shù)結(jié)果是then2;等等。事實(shí)上,可以給出多個(gè)if/then 配對(duì)。如果value結(jié)果不等于給出的任何配對(duì)時(shí),Decode 結(jié)果就返回else 。
需要注意的是,這里的if、then及else 都可以是函數(shù)或計(jì)算表達(dá)式。
2 DECODE 的簡(jiǎn)單例子
Oracle系統(tǒng)中就有許多數(shù)據(jù)字典是使用decode 思想設(shè)計(jì)的,比如記錄會(huì)話(huà)信息的V$SESSION數(shù)據(jù)字典視圖就是這樣。我們從《Oracle8i/9i Reference》資料中了解到,當(dāng)用戶(hù)登錄成功后在V$SESSION中就有該用戶(hù)的相應(yīng)記錄,但用戶(hù)所進(jìn)行的命令操作在該視圖中只記錄命令的代碼(0—沒(méi)有任何操作,2—Insert…),而不是具體的命令關(guān)鍵字。因此,我們需要了解當(dāng)前各個(gè)用戶(hù)的名字及他們所進(jìn)行的操作時(shí),要用下面命令才能得到詳細(xì)的結(jié)果:
select sid,serial#,username,
DECODE(command,
0,’None’,
2,’Insert’,
3,’Select’,
6,’Update’,
7,’Delete’,
8,’Drop’,
‘Other’) cmmand
from v$session where username is not null;
3 DECODE實(shí)現(xiàn)表的轉(zhuǎn)置
數(shù)據(jù)庫(kù)中的表是由列和行構(gòu)成的一個(gè)二維表。一般列在任何數(shù)據(jù)庫(kù)中都是有限的數(shù)量,而行的變化較大,如果表很大,行的數(shù)量可能大上千萬(wàn)行。同一列的不同行可能有不同的值,而且不是預(yù)先定義的。
除上面描述表具有的一些特點(diǎn)外,有一些表可以看成是不變的或者是較穩(wěn)定的,比如住房公積金系統(tǒng)是各個(gè)單位按照職工的工資數(shù)的比例交到本地的經(jīng)辦行中,它的處理流程如下:
例1.住房公積金報(bào)表置換實(shí)例:
1.各個(gè)單位在本地經(jīng)辦行進(jìn)行開(kāi)戶(hù),開(kāi)戶(hù)就是將單位的基本信息和職工信息的進(jìn)行登記;
2.每月各個(gè)單位的會(huì)計(jì)到經(jīng)辦行交繳本單位的所有職工的住房公積金,系統(tǒng)記錄有每個(gè)職工的交繳明細(xì)并在每條記錄上記錄有經(jīng)辦行的代碼;
3.每月、季、半年及年終都要求將經(jīng)辦行 變?yōu)?#8220;列”給出個(gè)月的明細(xì)報(bào)表:
經(jīng)辦行:城西區(qū) 城東區(qū) 。 。 。
月份:
2001.01 xxxx1.xx xxxxx2.xx
2001.02 xxxx3.xx xxxxx4.xx
。 。 。 。 。 。
原來(lái)的數(shù)據(jù)順序是:
城西區(qū)2001.01 xxxxx1.xx
城東區(qū)2001.01 xxxxx2.xx
城西區(qū)2001.02 xxxxx3.xx
城東區(qū)2001.02 xxxxx4.xx
住房公積金系統(tǒng)記錄職工的每月交繳名細(xì)的pay_lst表結(jié)構(gòu)是:
bank_code varchar2(6)NOT NULL, -- 經(jīng)辦行代碼
acc_no varchar2(15) not null, -- 單位代碼(單位帳號(hào))
emp_acc_no varchar2(20) not null, -- 職工帳號(hào)
tran_date date not null, -- 交繳日期
tran_val Number(7,2) not null, -- 交繳額
sys_date date default sysdate, --系統(tǒng)日期
oper_id varchar2(10) --操作員代碼
這樣的表結(jié)構(gòu),一般按照將經(jīng)辦行作為行(row)進(jìn)行統(tǒng)計(jì)是很容易的,但是如果希望將經(jīng)辦行變?yōu)榱?/span>(column)這樣的格式來(lái)輸出就有困難。如果用DECODE函數(shù)來(lái)處理則變得很簡(jiǎn)單:
我們創(chuàng)建一個(gè)視圖來(lái)對(duì)目前的pay_lst表進(jìn)行查詢(xún)。將經(jīng)辦行代碼變?yōu)橐恍┚唧w的經(jīng)辦行名稱(chēng)即可:
CREATE OR REPLACE VIEW bank_date_lst AS
Select to_char(tran_date,’yyyy.mm’),
SUM( DECODE ( bank_code,’001’, tran_val,0 )) 城西區(qū),
SUM( DECODE ( bank_code,’002’, tran_val,0 )) 城南區(qū),
SUM( DECODE ( bank_code,’003’, tran_val,0 )) 城東區(qū)
FROM pay_lst
GROUP BY to_char(tran_date,’yyyy.mm’);
建立視圖后,可直接對(duì)該視圖進(jìn)行查詢(xún)就可按照列顯示出結(jié)果。
例2.希望將下面的列結(jié)果按照列的方式來(lái)顯示JOB內(nèi)容:
SQL> select empno,ename,job,sal,deptno from emp
2 order by deptno,job;
EMPNO ENAME JOB SAL DEPTNO
---------- ---------- --------- ---------- ----------
7934 MILLER CLERK 1300 10
7782
7839 KING PRESIDENT 5000 10
7788 SCOTT ANALYST 3000 20
7369 SMITH CLERK 800 20
7876
7566 JONES MANAGER 2975 20
7938 趙元杰 軟件 12345 20
7698 BLAKE MANAGER 2850 30
7499 ALLEN SALESMAN 1600 30
7654 MARTIN SALESMAN 1250 30
7844 TURNER SALESMAN 1500 30
7521 WARD SALESMAN 1250 30
18 rows selected.
再看下面的查詢(xún)結(jié)果:
SQL> select deptno,job,sum(sal) from emp group by deptno,job;
DEPTNO JOB SUM(SAL)
---------- --------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
20 ANALYST 3000
20 CLERK 1900
20 MANAGER 2975
20 軟件 74070
30 MANAGER 2850
30 SALESMAN 5600
9 rows selected.
從上面的結(jié)果看,如果希望將JOB置換成列的方式,則只要用DECODE將JOB列進(jìn)行描述即可。創(chuàng)建的視圖如下:
create or replace view empv as
select deptno,
sum( decode(job,’ANALYST’, sal,0)) ANALYST,
sum( decode(job,’CLERK’, sal,0)) CLERK,
sum( decode(job,’MANAGER’, sal,0)) MANAGER,
sum( decode(job,’PRESIDENT’, sal,0)) PRESIDENT,
sum( decode(job,’SALESMAN’, sal,0)) SALESMAN,
sum( decode(job,’軟件’, sal,0)) 軟件
from emp group by deptno;
具體運(yùn)行的顯示樣本如下:
SQL> create or replace view empv as
2 select deptno,
3 sum( decode(job,'ANALYST', sal,0)) ANALYST,
4 sum( decode(job,'CLERK', sal,0)) CLERK,
5 sum( decode(job,'MANAGER', sal,0)) MANAGER,
6 sum( decode(job,'PRESIDENT', sal,0)) PRESIDENT,
7 sum( decode(job,'SALESMAN', sal,0)) SALESMAN,
8 sum( decode(job,'軟件', sal,0)) 軟件
9 from emp group by deptno;
View created.
SQL> select * from empv;
DEPTNO ANALYST CLERK MANAGER PRESIDENT SALESMAN 軟件
---------- ---------- ---------- ---------- ---------- ----------10 0 1300 2450 5000 0 0
20 3000 1900 2975 0 0 74070
30 0 0 2850 0 5600 0
posted on 2008-11-13 15:59 秋楓故事 閱讀(2929) 評(píng)論(0) 編輯 收藏