日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Oracle 数据库中较为复杂或典型的 SQL 语句的解读

發(fā)布時(shí)間:2023/12/3 数据库 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle 数据库中较为复杂或典型的 SQL 语句的解读 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 批量生成 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í)行過程如下:

  • 先打開表 student 和 course
  • 接著根據(jù)關(guān)聯(lián)條件(s.course_id=c.course_id)將 student 和 course 將兩張表進(jìn)行關(guān)聯(lián)
  • 接著將匹配結(jié)果生成一張?zhí)摫?#xff0c;即將符合條件的兩張表的數(shù)據(jù)合并成一張?zhí)摫?v1
  • 再根據(jù) where 條件把虛表 v1 中符合 c.course_id='0707' 的記錄篩選出來,生成虛表 v2
  • 最后執(zhí)行 select 子句把指定字段的數(shù)據(jù)獲取到,生成虛表 v3,v3 就是最后的查詢結(jié)果
  • 左外連接 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í)行順序如下:

  • 數(shù)據(jù)庫先執(zhí)行 from,打開表 emp_lwx 和 dept_lwx
  • 接著執(zhí)行 on,根據(jù)關(guān)聯(lián)字段把兩張表關(guān)聯(lián)起來
  • 接著執(zhí)行 inner join,把匹配的數(shù)據(jù)取出生成一張?zhí)摫?v1
  • 接著執(zhí)行 select 子句,在虛表 v1 中取出相關(guān)的數(shù)據(jù)生成虛表 v2
  • 接著執(zhí)行 distinct,將虛表 v2 中 deptno 和 dname 都重復(fù)的數(shù)據(jù)過濾掉,生成虛表 v3,此虛表 v3 就是最后的查詢結(jié)果
  • 關(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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。