Oracle 数据库中较为复杂或典型的 SQL 语句的解读
文章目錄
- 批量生成 SQL 語句/拼接字符串
- 多表關聯查詢 + where 子句
- 示例(一)
- 示例(二)
- 普通的表間內連接查詢語句
- 關鍵字 distinct 用法說明
- Oracle 數據庫的分組排序查詢
- Oracle 數據庫 cast 函數
- Oracle 數據庫 sum 函數的高級用法
- Oracle 數據庫多層子查詢嵌套查詢
- 關聯子查詢
- 數據庫如何把縱向列表轉換成橫向列表
批量生成 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 語句解釋:
|| 是表示兩段字符串拼接起來,' ' 里面是拼接的字符串, ' '' ' 表示字符串里面有個單引號,'' 表示一個單引號哦。
t.a1 表示取 t 表的 a1 字段的值,注意變量不要加任何的引號哦。
注意:
Oracle 數據庫字符串拼接符號 ||,而MySQL 數據庫的字符串拼接使用函數 concat(str1,str2),str1、str2 是指要拼接的兩個字符串
多表關聯查詢 + 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';上述查詢語句執行過程如下:
左外連接 left outer join 執行效果說明:
left outer join 的查詢結果是這樣的,如果匹配成功的那么兩張表的相關字段的數據會提取出來,如果匹配不成功的,則左邊的數據提取出來,右邊表的相應字段值則為空。
錯誤理解:
這個 where 子句并不是先對 course 表進行篩選再和 student 表進行關聯查詢,而是進行關聯匹配的同時進行篩選,匹配成功且符合篩選條件的記錄才提取出來,如果只是匹配成功但是不符合篩選條件的剔除掉。
示例(二)
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';執行過程簡單說明:
數據庫是按照這樣的順序來執行 SQL 語句的,首先 securiorg 和 t_pf_datadict 兩張表通過 s.tecgrd=d.code 關聯條件進行做左連接,這樣就得到連接后的結果集,再執行 where 語句進行篩選,再執行 select 語句得到最后想要的結果集。
普通的表間內連接查詢語句
select distinct e.deptno,d.dname from emp_lwx e inner join dept_lwx d on e.deptno=d.deptno;分析上述 SQL 語句的內部執行順序如下:
關鍵字 distinct 用法說明
select distinct deptno,job from emp_lwx;distinct 關鍵字不是作用在字段 deptno 上,在執行 select 子句的時候,數據庫是這樣判斷的,取出 deptno 和 job 的數據,這兩個字段的數據聯合起來在結果集中是唯一的就可以了,這個兩個字段的數據就構成結果集中的一條記錄,只要這條記錄在整個結果集中是唯一的就OK了。
Oracle 數據庫的分組排序查詢
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;說明:
先執行 FROM,接著執行 SELECT,接著執行 PARTITION BY,最后執行 ORDER BY。對 SELECT 出來的結果集按 ENTITYID 進行分組,每組再按 CREDATE 和 EXACTCRETIME 排序,順序號的字段名為 RNUM,查詢得到的結果如下圖所示:
Oracle 數據庫 cast 函數
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函數的作用是類型轉換,在此就是將LEV 字段的數據類型轉換成VARCHAR2(3)
Oracle 數據庫 sum 函數的高級用法
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;解讀:
先對整個表進行遍歷分組,然后判斷每組里面每條記錄 BILLSTATE 字段的值,如果是 1 則累加 1 ,否則累加 0,最后的累加值顯示一列,列名為:未使用;如果是2或3或4則將累加 1,否則累加 0,最后的值顯示一列,列名為:已使用;如果是 5 則累加 1,否則累加 0,最后的值顯示一列,列名為:已遺失。
Oracle 數據庫多層子查詢嵌套查詢
SELECT DEPNAME 運管機構,SUM(已作廢) 已作廢,SUM(已反饋) 已反饋,SUM(未使用) 未使用,SUM(已使用) 已使用 FROM (SELECT DEPNAME,CASE 牌證狀態 WHEN '已作廢' THEN TOTAL END AS 已作廢,CASE 牌證狀態 WHEN '已反饋' THEN TOTAL END AS 已反饋,CASE 牌證狀態 WHEN '未使用' THEN TOTAL END AS 未使用,CASE 牌證狀態 WHEN '已使用' THEN TOTAL END AS 已使用 FROM (SELECT D1.DEPNAME,B1.牌證狀態,B1.TOTAL FROM (SELECT T1.DEPCODE, CASE BILLSTATE WHEN '2' THEN '已使用' WHEN '3' THEN '已作廢' WHEN '4' THEN '已反饋' WHEN '5' THEN '遺失' ELSE '未使用' END AS 牌證狀態,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;注意: 先對某張表進行篩選再關聯其它表是不可以的,對某個表先進行分組再篩選也是不可以的,會報錯
關聯子查詢
select ename, salary, deptno from emp_xxx a where salary < ( select avg(nvl(salary,0)) from emp_xxx where deptno = a.deptno; // 子查詢需要依賴主查詢傳遞過來的參數 a.deptno解讀:
數據庫的指針先指向 emp_xxx 的第一條記錄,然后將當前記錄的deptno的值傳遞給子查詢,接著數據庫開始執行子查詢,計算出參數deptno的值所對應的部門的平均工資,接著又回到主查詢判斷當前記錄的salary值是否小于平均工資,如果小于則添加到結果集,接著指針移到下條記錄,重復上一次的查詢動作,如果當前記錄不小于平均工資,則直接將指針移到下條記錄,重復上一次的查詢動作。這樣就可以查詢出所有薪水比本部門平均工資低的員工數據。
我們知道數據庫服務器執行SQL語句是有按照先后順序的,例如:select ename,salary from emp_lwx where salary >3000;
順序是這樣的,數據庫服務器首先打開emp_lwx表,然后執行where語句,按照where子句的條件來篩選符合條件的記錄,服務器是對整個表從上至下進行全盤掃描,逐條判斷記錄是否符合條件,然后把符合條件的記錄全部放在內存的一個虛表中,然后才執行select子句的,是符合條件的記錄全部篩選出來后才執行select子句,而不是篩選一條記錄就執行一次select子句,當然執行select子句也是從上至下逐條取出所需的數據,如果是組函數的話,那么就逐條記錄取出所需的數據后再進行函數運算的。
數據庫如何把縱向列表轉換成橫向列表
縱向列表,如下圖所示:
如何變成橫向列表,如下圖所示:
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;解讀下:
很明顯這是一個關聯子查詢,執行順序是這樣的,首先主查詢 from ym 0 group by year 是先打開ym這張表,然后根據year字段來分組,接著執行select語句,指針先移至第一組,獲取第一組的year值,也就是1991,然后執行關聯子查詢了,這時會把第一組的年份1991傳入子查詢中,那么第一個子查詢就根據 month=‘1’ and year=‘1991’ 獲取到相應的 amount值,字段名是m1,接著執行第二個子查詢了,同樣是將第一組的年份1991傳入,得到相應的amont值,直到4個子查詢都執行完畢,這樣就得到第一條記錄。那么指針就移到第二組了,同上一輪一樣取出相應的值,那么最后得到的結果就是第2條記錄了。
注意:這里的指針按組移動,取到年份值后分別傳給四個子查詢!
總結
以上是生活随笔為你收集整理的Oracle 数据库中较为复杂或典型的 SQL 语句的解读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JSP 活动元素 <jsp:direct
- 下一篇: Oracle/MySQL数据库的表间关联