Oracle 数据库中较为复杂或典型的 SQL 语句的解读
文章目錄
- 批量生成 SQL 語句/拼接字符串
- 多表關(guān)聯(lián)查詢 + where 子句
- 示例(一)
- 示例(二)
 
- 普通的表間內(nèi)連接查詢語句
- 關(guān)鍵字 distinct 用法說明
 
- Oracle 數(shù)據(jù)庫的分組排序查詢
- Oracle 數(shù)據(jù)庫 cast 函數(shù)
- Oracle 數(shù)據(jù)庫 sum 函數(shù)的高級(jí)用法
- Oracle 數(shù)據(jù)庫多層子查詢嵌套查詢
- 關(guān)聯(lián)子查詢
- 數(shù)據(jù)庫如何把縱向列表轉(zhuǎn)換成橫向列表
 
批量生成 SQL 語句/拼接字符串
select 'update t_pf_menu set a1='''||t.a1||''' where a2='''|| t.a2||''';' from tesst t; select 'update t_busop set busname='''||t.busname||''',icon='''||t.icon||''' where busopid='''|| t.busopid||''';' from lwx t;SQL 語句解釋:
|| 是表示兩段字符串拼接起來,' ' 里面是拼接的字符串, ' '' ' 表示字符串里面有個(gè)單引號(hào),'' 表示一個(gè)單引號(hào)哦。
 t.a1 表示取 t 表的 a1 字段的值,注意變量不要加任何的引號(hào)哦。
注意:
 Oracle 數(shù)據(jù)庫字符串拼接符號(hào) ||,而MySQL 數(shù)據(jù)庫的字符串拼接使用函數(shù) concat(str1,str2),str1、str2 是指要拼接的兩個(gè)字符串
多表關(guān)聯(lián)查詢 + where 子句
示例(一)
select s.name,s.age,c.course_name from student s left outer join course c on s.course_id=c.course_id where c.course_id='0707';上述查詢語句執(zhí)行過程如下:
左外連接 left outer join 執(zhí)行效果說明:
left outer join 的查詢結(jié)果是這樣的,如果匹配成功的那么兩張表的相關(guān)字段的數(shù)據(jù)會(huì)提取出來,如果匹配不成功的,則左邊的數(shù)據(jù)提取出來,右邊表的相應(yīng)字段值則為空。
錯(cuò)誤理解:
這個(gè) where 子句并不是先對(duì) course 表進(jìn)行篩選再和 student 表進(jìn)行關(guān)聯(lián)查詢,而是進(jìn)行關(guān)聯(lián)匹配的同時(shí)進(jìn)行篩選,匹配成功且符合篩選條件的記錄才提取出來,如果只是匹配成功但是不符合篩選條件的剔除掉。
示例(二)
select cmcltname,jurperson,special,d.name,ecotype,depcode from $prdline.securiorg s left outer join $platform.t_pf_datadict d on s.tecgrd=d.code where d.ddfld='tecgrd';執(zhí)行過程簡(jiǎn)單說明:
 數(shù)據(jù)庫是按照這樣的順序來執(zhí)行 SQL 語句的,首先 securiorg 和 t_pf_datadict 兩張表通過 s.tecgrd=d.code 關(guān)聯(lián)條件進(jìn)行做左連接,這樣就得到連接后的結(jié)果集,再執(zhí)行 where 語句進(jìn)行篩選,再執(zhí)行 select 語句得到最后想要的結(jié)果集。
普通的表間內(nèi)連接查詢語句
select distinct e.deptno,d.dname from emp_lwx e inner join dept_lwx d on e.deptno=d.deptno;分析上述 SQL 語句的內(nèi)部執(zhí)行順序如下:
關(guān)鍵字 distinct 用法說明
select distinct deptno,job from emp_lwx;distinct 關(guān)鍵字不是作用在字段 deptno 上,在執(zhí)行 select 子句的時(shí)候,數(shù)據(jù)庫是這樣判斷的,取出 deptno 和 job 的數(shù)據(jù),這兩個(gè)字段的數(shù)據(jù)聯(lián)合起來在結(jié)果集中是唯一的就可以了,這個(gè)兩個(gè)字段的數(shù)據(jù)就構(gòu)成結(jié)果集中的一條記錄,只要這條記錄在整個(gè)結(jié)果集中是唯一的就OK了。
Oracle 數(shù)據(jù)庫的分組排序查詢
SELECT T.ENTITYID,T.CREDATE,T.EXACTCRETIME,ROW_NUMBER() OVER(PARTITION BY T.ENTITYID ORDER BY CREDATE DESC,EXACTCRETIME DESC) AS RNUM FROM HYT2PRDHN.TASKED T;說明:
 先執(zhí)行 FROM,接著執(zhí)行 SELECT,接著執(zhí)行 PARTITION BY,最后執(zhí)行 ORDER BY。對(duì) SELECT 出來的結(jié)果集按 ENTITYID 進(jìn)行分組,每組再按 CREDATE 和 EXACTCRETIME 排序,順序號(hào)的字段名為 RNUM,查詢得到的結(jié)果如下圖所示:
 
Oracle 數(shù)據(jù)庫 cast 函數(shù)
SELECT CODE,NAME,CAST(CASE WHEN CODE LIKE '%000' THEN 1 WHEN CODE LIKE '%00' THEN 2 ELSE 3 END AS VARCHAR2(3)) AS LEV FROM T_PF_DATADICT WHERE DDFLD='BNSCOPE' AND CODE IN ('08000','08100','08101','08102','08103','08200','08201','08300','08301') ORDER BY CODE解讀:
CAST函數(shù)的作用是類型轉(zhuǎn)換,在此就是將LEV 字段的數(shù)據(jù)類型轉(zhuǎn)換成VARCHAR2(3)
Oracle 數(shù)據(jù)庫 sum 函數(shù)的高級(jí)用法
select depcode,sum(case when BILLSTATE=1 then 1 else 0 end) as 未使用,sum(case when BILLSTATE in (2,3,4) then 1 else 0 end) as 已使用,sum(case when BILLSTATE in (5) then 1 else 0 end) as 已遺失 from BCBILLSTOCK group by depcode;解讀:
先對(duì)整個(gè)表進(jìn)行遍歷分組,然后判斷每組里面每條記錄 BILLSTATE 字段的值,如果是 1 則累加 1 ,否則累加 0,最后的累加值顯示一列,列名為:未使用;如果是2或3或4則將累加 1,否則累加 0,最后的值顯示一列,列名為:已使用;如果是 5 則累加 1,否則累加 0,最后的值顯示一列,列名為:已遺失。
Oracle 數(shù)據(jù)庫多層子查詢嵌套查詢
SELECT DEPNAME 運(yùn)管機(jī)構(gòu),SUM(已作廢) 已作廢,SUM(已反饋) 已反饋,SUM(未使用) 未使用,SUM(已使用) 已使用 FROM (SELECT DEPNAME,CASE 牌證狀態(tài) WHEN '已作廢' THEN TOTAL END AS 已作廢,CASE 牌證狀態(tài) WHEN '已反饋' THEN TOTAL END AS 已反饋,CASE 牌證狀態(tài) WHEN '未使用' THEN TOTAL END AS 未使用,CASE 牌證狀態(tài) WHEN '已使用' THEN TOTAL END AS 已使用 FROM (SELECT D1.DEPNAME,B1.牌證狀態(tài),B1.TOTAL FROM (SELECT T1.DEPCODE, CASE BILLSTATE WHEN '2' THEN '已使用' WHEN '3' THEN '已作廢' WHEN '4' THEN '已反饋' WHEN '5' THEN '遺失' ELSE '未使用' END AS 牌證狀態(tài),SUM(CNT) TOTAL FROM BCBILLSTOCK T1 GROUP BY DEPCODE,BILLSTATE) B1 LEFT JOIN HYT2PRDHN.T_PF_DEP D1 ON B1.DEPCODE=D1.DEPCODE)) GROUP BY DEPNAME;注意: 先對(duì)某張表進(jìn)行篩選再關(guān)聯(lián)其它表是不可以的,對(duì)某個(gè)表先進(jìn)行分組再篩選也是不可以的,會(huì)報(bào)錯(cuò)
關(guān)聯(lián)子查詢
select ename, salary, deptno from emp_xxx a where salary < ( select avg(nvl(salary,0)) from emp_xxx where deptno = a.deptno; // 子查詢需要依賴主查詢傳遞過來的參數(shù) a.deptno解讀:
 數(shù)據(jù)庫的指針先指向 emp_xxx 的第一條記錄,然后將當(dāng)前記錄的deptno的值傳遞給子查詢,接著數(shù)據(jù)庫開始執(zhí)行子查詢,計(jì)算出參數(shù)deptno的值所對(duì)應(yīng)的部門的平均工資,接著又回到主查詢判斷當(dāng)前記錄的salary值是否小于平均工資,如果小于則添加到結(jié)果集,接著指針移到下條記錄,重復(fù)上一次的查詢動(dòng)作,如果當(dāng)前記錄不小于平均工資,則直接將指針移到下條記錄,重復(fù)上一次的查詢動(dòng)作。這樣就可以查詢出所有薪水比本部門平均工資低的員工數(shù)據(jù)。
我們知道數(shù)據(jù)庫服務(wù)器執(zhí)行SQL語句是有按照先后順序的,例如:select ename,salary from emp_lwx where salary >3000;
 順序是這樣的,數(shù)據(jù)庫服務(wù)器首先打開emp_lwx表,然后執(zhí)行where語句,按照where子句的條件來篩選符合條件的記錄,服務(wù)器是對(duì)整個(gè)表從上至下進(jìn)行全盤掃描,逐條判斷記錄是否符合條件,然后把符合條件的記錄全部放在內(nèi)存的一個(gè)虛表中,然后才執(zhí)行select子句的,是符合條件的記錄全部篩選出來后才執(zhí)行select子句,而不是篩選一條記錄就執(zhí)行一次select子句,當(dāng)然執(zhí)行select子句也是從上至下逐條取出所需的數(shù)據(jù),如果是組函數(shù)的話,那么就逐條記錄取出所需的數(shù)據(jù)后再進(jìn)行函數(shù)運(yùn)算的。
數(shù)據(jù)庫如何把縱向列表轉(zhuǎn)換成橫向列表
縱向列表,如下圖所示:
如何變成橫向列表,如下圖所示:
 
SQL語句是這樣寫的:
select o.year,(select n.amount from ym n where n.month='1' and n.year=o.year) as m1,(select n.amount from ym n where n.month='2' and n.year=o.year) as m2,(select n.amount from ym n where n.month='3' and n.year=o.year) as m3,(select n.amount from ym n where n.month='4' and n.year=o.year) as m4 from ym o group by year;解讀下:
很明顯這是一個(gè)關(guān)聯(lián)子查詢,執(zhí)行順序是這樣的,首先主查詢 from ym 0 group by year 是先打開ym這張表,然后根據(jù)year字段來分組,接著執(zhí)行select語句,指針先移至第一組,獲取第一組的year值,也就是1991,然后執(zhí)行關(guān)聯(lián)子查詢了,這時(shí)會(huì)把第一組的年份1991傳入子查詢中,那么第一個(gè)子查詢就根據(jù) month=‘1’ and year=‘1991’ 獲取到相應(yīng)的 amount值,字段名是m1,接著執(zhí)行第二個(gè)子查詢了,同樣是將第一組的年份1991傳入,得到相應(yīng)的amont值,直到4個(gè)子查詢都執(zhí)行完畢,這樣就得到第一條記錄。那么指針就移到第二組了,同上一輪一樣取出相應(yīng)的值,那么最后得到的結(jié)果就是第2條記錄了。
注意:這里的指針按組移動(dòng),取到年份值后分別傳給四個(gè)子查詢!
總結(jié)
以上是生活随笔為你收集整理的Oracle 数据库中较为复杂或典型的 SQL 语句的解读的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: JSP 活动元素 <jsp:direct
- 下一篇: 国际通用语言有几种 国际通用语言的介绍
