Oracle資料庫----高階查詢
1. SQL(高階查詢)
1.1. 子查詢
1.1.1. 子查詢在WHERE子句中
在SELECT查詢中,在WHERE查詢條件中的限制條件不是一個確定的值,而是來自於另外一個查詢的結果。為了給查詢提供資料而首先執行的查詢語句叫做子查詢。
子查詢:嵌入在其它SQL語句中的SELECT語句,大部分時候出現在WHERE子句中。子查詢嵌入的語句稱作主查詢或父查詢。主查詢可以是SELECT語句,也可以是其它型別的語句比如DML或DDL語句。
根據返回結果的不同,子查詢可分為單行子查詢、多行子查詢及多列子查詢。
圖-1子查詢
例如查詢和SCOTT同職位的員工:
SELECTe.ename, e.job
FROM emp e
WHEREe.job =
(SELECT job FROM emp WHEREename = 'SCOTT');
查詢薪水比整個機構平均薪水高的員工:
- SELECTdeptno, ename, sal
- FROM emp e
- WHEREsal> (SELECTAVG(sal) FROMemp);
如果子查詢返回多行,主查詢中要使用多行比較操作符,包括IN、ALL、ANY。其中ALL和ANY不能單獨使用,需要配合單行比較操作符>、>=、<、<=一起使用。例如查詢出部門中有SALESMAN但職位不是SALESMAN的員工的資訊:
SELECTempno, ename, job, sal,
FROM emp
WHERE deptno IN
(SELECT deptno FROM emp WHEREjob = 'SALESMAN')
ANDjob <> 'SALESMAN';
在子查詢中需要引用到主查詢的欄位資料,使用EXISTS關鍵字。EXISTS後邊的子查詢至少返回一行資料,則整個條件返回TRUE。如果子查詢沒有結果,則返回FALSE。例如列出來那些有員工的部門資訊:
- SELECTdeptno, dname FROM dept d
- WHERE EXISTS
- (SELECT * FROM emp e
- WHEREd.deptno = e.deptno);
1.1.2. 子查詢在HAVING部分
子查詢不僅可以出現在WHERE子句中,還可以出現在HAVING部分。例如查詢列出最低薪水高於部門30的最低薪水的部門資訊:
SELECTdeptno, MIN(sal) min_sal
FROM emp
GROUP BY deptno
HAVINGMIN(sal) >
(SELECTMIN(sal) FROM emp WHEREdeptno = 30);
1.1.3. 子查詢在FROM部分
在查詢語句中,FROM子句用來指定要查詢的表。如果要在一個子查詢的結果中繼續查詢,則子查詢出現在FROM 子句中,這個子查詢也稱作行內檢視或者匿名檢視。這時,把子查詢當作檢視對待,但檢視沒有名字,只能在當前的SQL語句中有效。
查詢出薪水比本部門平均薪水高的員工資訊:
- SELECTe.deptno, e.ename, e.sal
- FROM empe,
- (SELECTdeptno, AVG(sal) avg_sal FROM emp GROUP BYdeptno) x
- WHEREe.deptno = x.deptno
- ande.sal>x.avg_sal
- ORDER BYe.deptno;
1.1.4. 子查詢在SELECT部分
把子查詢放在SELECT子句部分,可以認為是外連線的另一種表現形式,使用更靈活:
SELECTe.ename, e.sal, e.deptno,
(SELECTd.deptno FROM dept d
WHEREd.deptno = e.deptno) deptno
FROM empe;
1.2. 分頁查詢
1.2.1. ROWNUM
ROWNUM被稱作偽列,用於返回標識行資料順序的數字。例如:
- SELECTROWNUM, empno, ename, sal
- FROMemp;
ROWNUM只能從1計數,不能從結果集中直接擷取。下面的查詢語句將沒有結果:
SELECTROWNUM, empno, ename, sal
FROM emp
WHERErownum> 3;
如果利用ROWNUM擷取結果集中的部分資料,需要用到行內檢視:
- SELECT * FROM
- (SELECTROWNUMrn , e.* FROM empe )
- WHERE rn BETWEEN 8 AND 10;
也就是將ROWNUM先作為行內檢視的一個列,在主查詢中就可以使用這個列值作為條件。
1.2.2. 使用子查詢進行分頁
分頁策略是指每次只取一頁的資料。當每次換頁,取下一頁的資料。在ORACLE中利用ROWNUM的功能來進行分頁。
假設結果集共105條,每20條分為一頁,則共6頁:
Page1: 1 至 20
Page2: 21 至40
…
PageN: (n - 1) * pageSize + 1 至 n * pageSize
1.2.3. 分頁與ORDER BY
按薪水倒序排列,取出結果集中第8到第10條的記錄:
SELECT * FROM
(SELECTROWNUMrn , t.* FROM
(SELECTempno,ename,sal FROM emp
ORDER BY salDESC) t
)
WHERE rn BETWEEN 8 AND 10;
根據要檢視的頁數,計算起點值((n - 1) * pageSize + 1)和終點值(n * pageSize),替換掉BETWEEN和AND的引數,即得到當前頁的記錄。
1.3. DECODE函式
1.3.1. DECODE函式基本語法
DECODE函式的語法如下:
DECODE (expr, search1, result1[, search2, result2…][, default])
它用於比較引數expr的值,如果匹配到哪一個search條件,就返回對應的result結果,可以有多組search和result的對應關係,如果任何一個search條件都沒有匹配到,則返回最後default的值。default引數是可選的,如果沒有提供default引數值,當沒有匹配到時,將返回NULL。
查詢職員表,根據職員的職位計算獎勵金額,當職位分別是’MANAGER’、’ANALYST’、’SALESMAN’時,獎勵金額分別是薪水的1.2倍、1.1倍、1.05倍,如果不是這三個職位,則獎勵金額取薪水值:
- SELECTename, job, sal,
- DECODE(job, 'MANAGER', sal * 1.2,
- 'ANALYST', sal * 1.1,
- 'SALESMAN', sal * 1.05,
- sal
- ) bonus
- FROMemp;
和DECODE函式功能相似的有CASE語句,實現類似於if-else的操作。
SELECTename, job, sal,
CASE jobWHEN 'MANAGER' THENsal * 1.2
WHEN 'ANALYST' THENsal * 1.1
WHEN 'SALESMAN' THENsal * 1.05
ELSE sal END
bonus
FROMemp;
1.3.2. DECODE函式在分組查詢中的應用
DECODE函式可以按欄位內容分組,例如:計算職位的人數,analyst/manager職位屬於vip,其餘是普通員工operation,這種功能無法用GROUP BY簡單實現。用decode的實現方式:
- SELECTDECODE(job, 'ANALYST', 'VIP',
- 'MANAGER', 'VIP',
- 'OPERATION') job,
- COUNT(1) job_cnt
- FROM emp
- GROUP BYDECODE(job, 'ANALYST', 'VIP', 'MANAGER', 'VIP', 'OPERATION');
圖-2DECODE函式的執行結果
DECODE函式也可以按欄位內容排序,例如:Dept表中按”研發部”、“市場部”、“銷售部”排序,用普通的select語句,無法按照字面資料排序:
SELECTdeptno, dname, loc
FROM dept
ORDER BY
DECODE(dname, '研發部',1,'市場部',2,'銷售部',3), loc;
1.4. 排序函式
1.4.1. ROW_NUMBER
ROW_NUMBER語法如下:
- ROW_NUMBER() OVER(
- PARTITION BY col1 ORDER BYcol2)
表示根據col1分組,在分組內部根據col2排序。此函式計算的值就表示每組內部排序後的順序編號,組內連續且唯一。
ROWNUM是偽列, ROW_NUMBER功能更強,可以直接從結果集中取出子集。
場景:按照部門編碼分組顯示,每組內按職員編碼排序,並賦予組內編碼
SELECTdeptno, ename, empno,
ROW_NUMBER()
OVER (PARTITION BY deptno ORDER BYempno) ASemp_id
FROMemp;
1.4.2. RANK
RANK函式的語法如下:
- RANK() OVER(
- PARTITION BY col1 ORDER BYcol2)
表示根據col1分組,在分組內部根據col2給予等級標識,即排名,相同的資料返回相同排名。特點是跳躍排序,如果有相同資料,則排名相同,比如並列第二,則兩行資料都標記為2,但下一位將是第四名。
和ROW_NUMBER的區別是有結果有重複值,而ROW_NUMBER沒有。
場景:按照部門編碼分組,同組內按薪水倒序排序,相同薪水則按獎金數正序排序,並給予組內等級,用Rank_ID表示
SELECTdeptno, ename, sal, comm,
RANK() OVER (PARTITION BY deptno
ORDER BY salDESC, comm) "Rank_ID"
FROM emp;
1.4.3. DENSE_RANK
DENSE_RANK函式的語法如下:
- DENSE_RANK() OVER(
- PARTITION BY col1 ORDER BYcol2)
表示根據col1分組,在分組內部根據col2給予等級標識,即排名,相同的資料返回相同排名。特點是連續排序,如果有並列第二,下一個排序將是三,這一點是和RANK的不同,RANK是跳躍排序。
場景:關聯emp和dept表,按照部門編碼分組,每組內按照員工薪水排序,列出員工的部門名字、姓名和薪水:
SELECTd.dname, e.ename, e.sal,
DENSE_RANK()
OVER (PARTITION BYe.deptno ORDER BYe.sal)
AS drank
FROM emp e join dept d
one.deptno = d.deptno;
1.5. 高階分組函式
1.5.1. ROLLUP
ROLLUP、CUBE 和 GROUPING SETS 運算子是 GROUP BY 子句的擴充套件,可以生成與使用 UNION ALL 來組合單個分組查詢時相同的結果集,用來簡化和高效的實現統計查詢。語法形式如下:
- GROUP BY ROLLUP(a, b, c)
- GROUP BY CUBE(a, b, c)
- GROUP BY GROUPING SETS ( (a), (b))
假設有表test,有a、b、c、d四個列。
- SELECTa,b,c,SUM(d) FROM test GROUP BYROLLUP(a,b,c);
等價於:
SELECTa,b,c,SUM(d) FROM test GROUP BYa,b,c
UNION ALL
SELECTa,b,null,SUM(d) FROM test GROUP BYa,b
UNION ALL
SELECTa,null,null,SUM(d) FROM test GROUP BY a
UNION ALL
SELECTnull,null,null,sum(d) FROMtest;
對ROLLUP的列從右到左以一次少一列的方式進行分組直到所有列都去掉後的分組(也就是全表分組)。對於n個引數的ROLLUP,有n+1次分組。
表-1 資料樣例表
準備資料:
- SQL>DROP TABLEsales_tab;
- SQL>CREATE TABLEsales_tab (
- year_id NUMBER NOTNULL,
- month_id NUMBER NOTNULL,
- day_id NUMBER NOTNULL,
- sales_valueNUMBER(10,2) NOT NULL
- );
- SQL>INSERT INTOsales_tab
- SELECTTRUNC(DBMS_RANDOM.value(low => 2010, high => 2012)) ASyear_id,
- TRUNC(DBMS_RANDOM.value(low => 1, high => 13)) ASmonth_id,
- TRUNC(DBMS_RANDOM.value(low => 1, high => 32)) ASday_id,
- ROUND(DBMS_RANDOM.value(low => 1, high => 100), 2) ASsales_value
- FROM dual
- CONNECT BYlevel <= 1000;
- SQL>COMMIT;
複習組函式的用法:
SQL>SELECTSUM(sales_value) ASsales_value FROMsales_tab;
SQL>SELECTyear_id, COUNT(*) ASnum_rows,
SUM(sales_value) ASsales_value
FROMsales_tab
GROUP BYyear_id
ORDER BYyear_id;
SQL>SELECTyear_id, month_id,
COUNT(*) ASnum_rows,
SUM(sales_value) ASsales_value
FROMsales_tab
GROUP BYyear_id, month_id
ORDER BYyear_id, month_id;
圖-3 在測試表中使用組函式的執行結果
圖-4 在測試表中使用組函式的執行結果
ROLLUP函式的用法:
- SELECTyear_id, month_id,
- SUM(sales_value) ASsales_value
- FROMsales_tab
- GROUP BY
- ROLLUP (year_id, month_id)
- ORDER BYyear_id, month_id;
圖-5 在測試表中使用ROLLUP函式的執行結果
SELECTyear_id, month_id, day_id, SUM(sales_value) ASsales_value
FROMsales_tab
GROUP BYROLLUP (year_id, month_id, day_id)
ORDER BYyear_id, month_id, day_id;
圖-6 在測試表中使用ROLLUP函式的執行結果
1.5.2. CUBE
CUBE函式的語法形式:
- GROUP BYCUBE(a, b, c)
對cube的每個引數,都可以理解為取值為參與分組和不參與分組兩個值的一個維度,所有維度取值組合的集合就是分組後的集合。對於n個引數的cube,有2^n次分組。
如果GROUP BY CUBE(a,b,c),首先對(a,b,c)進行GROUP BY,然後依次是(a,b),(a,c),(a),(b,c),(b),(c),最後對全表進行GROUP BY操作,所以一共是2^3=8次分組。
SELECTa,b,c,SUM(d) FROM test GROUP BYCUBE(a,b,c);
等價於:
- SELECTa,b,c,SUM(d) FROM test GROUP BYa,b,c
- UNION ALL
- SELECTa,b,NULL,SUM(d) FROM test GROUP BYa,b
- UNION ALL
- SELECTa,NULL,c,SUM(d) FROM test GROUP BYa,c
- UNION ALL
- SELECTa,NULL,NULL,SUM(d) FROM test GROUP BY a
- UNION ALL
- SELECTNULL,b,c,SUM(d) FROM test GROUP BYb,c
- UNION ALL
- SELECTNULL,b,NULL,SUM(d) FROM test GROUP BY b
- UNION ALL
- SELECTNULL,NULL,c,SUM(d) FROM test GROUP BY c
- UNION ALL
- SELECTNULL,NULL,NULL,SUM(d) FROMtest ;
等價於只是方便理解,其內部執行機制並不相同,其效率遠高於UNION ALL。
在sales_value表中使用cube函式:
SELECTyear_id, month_id,
SUM(sales_value) ASsales_value
FROMsales_tab
GROUP BYCUBE (year_id, month_id)
ORDER BYyear_id, month_id;
圖-7在測試表中使用CUBE函式的執行結果
- SELECTyear_id, month_id, day_id,
- SUM(sales_value) ASsales_value
- FROMsales_tab
- GROUP BYCUBE (year_id, month_id, day_id)
- ORDER BYyear_id, month_id, day_id;
1.5.3. GROUPING SETS
GROUPING SETS 運算子可以生成與使用單個 GROUP BY、ROLLUP 或 CUBE 運算子所生成的結果集相同的結果集,但是使用更靈活。
如果不需要獲得由完備的 ROLLUP 或 CUBE 運算子生成的全部分組,則可以使用 GROUPING SETS 僅指定所需的分組。GROUPING SETS 列表可以包含重複的分組。
GROUPING SETS示例:
SELECTyear_id, month_id, SUM(sales_value)
FROMsales_tab
GROUP BYCUBE (year_id,month_id)
order by 1, 2;
SELECTyear_id, month_id, SUM(sales_value)
FROMsales_tab
GROUP BY GROUPINGSETS ( (year_id), (month_id))
order by 1, 2
其中分組方式示例如下:
- 使用GROUP BY GROUPING SETS(a,b,c),則對(a),(b),(c)進行GROUP BY
- 使用GROUP BY GROUPING SETS((a,b),c), 則對(a,b),(c)進行GROUP BY
- GROUPING BY GROUPING SET(a,a) , 則對(a)進行2次GROUP BY, GROUPING SETS的引數允許重複
1.6. 集合操作
1.6.1. UNION、UNION ALL
圖-8 集合操作
為了合併多個SELECT語句的結果,可以使用集合操作符,實現集合的並、交、差。
集合操作符包括UNION、UNION ALL、INTERSECT和MINUS。多條作集合操作的SELECT語句的列的個數和資料型別必須匹配。
ORDER BY子句只能放在最後的一個查詢語句中。
集合操作的語法如下:
- SELECT statement1
- [UNION | UNIONALL | INTERSECT | MINUS]
- SELECTstatement2;
UNION和UNION ALL用來獲取兩個或兩個以上結果集的並集:
- UNION操作符會自動去掉合併後的重複記錄。
- UNION ALL返回兩個結果集中的所有行,包括重複的行。
- UNION操作符對查詢結果排序,UNION ALL不排序。
例如,合併職位是’MANAGER’的員工和薪水大於2500的員工集合,檢視兩種方式的結果差別:
--Union
SELECTename, job, sal FROM emp
WHEREjob = 'MANAGER'
SELECTename, job, sal FROM emp
WHEREsal> 2500;
--Union all
SELECTename, job, sal FROM emp
WHEREjob = 'MANAGER'
SELECTename, job, sal FROM emp
WHEREsal> 2500;
1.6.2. INTERSECT
INTERSECT函式獲得兩個結果集的交集,只有同時存在於兩個結果集中的資料,才被顯示輸出。使用INTERSECT操作符後的結果集會以第一列的資料作升序排列。
例如:顯示職位是’MANAGER’的員工和薪水大於2500的員工的交集:
- SELECTename, job, sal FROM emp
- WHEREjob = 'MANAGER'
- INTERSECT
- SELECTename, job, sal FROM emp
- WHEREsal> 2500;
1.6.3. MINUS
MINUS函式獲取兩個結果集的差集。只有在第一個結果集中存在,在第二個結果集中不存在的資料,才能夠被顯示出來。也就是結果集一減去結果集二的結果。
例如:列出職位是MANAGER但薪水低於2500的員工記錄:
- SELECTename, job, sal FROM emp
- WHEREjob = 'MANAGER'
- MINUS
- SELECTename, job, sal FROM emp
- WHEREsal> 2500;
相關推薦
Oracle資料庫----高階查詢
1. SQL(高階查詢) 1.1. 子查詢 1.1.1. 子查詢在WHERE子句中在SELECT查詢中,在WHERE查詢條件中的限制條件不是一個確定的值,而是來自於另外一個查詢的結果。為了給查詢提供資料而首先執行的查詢語句叫做子查詢。子查詢:嵌入在其它SQL語句中的SELECT語句,大部分時候出現在WHERE
MySQL、SQL server 、Oracle資料庫中查詢所有的資料庫,查詢指定資料庫所有表名,查詢所有的欄位的名字
MySQL中查詢所有資料庫名和表名 1.查詢所有資料庫 show databases; 2.查詢指定資料庫中所有表名 select table_name from information_schema.tables where table_schema='database_name' a
hibernate連線oracle資料庫進行查詢
按主鍵查詢 dao層 public Emp get(Serializable id){ //通過session的get方法根據載入指定物件 return (Emp)HibernateUtil.currentSession().get(Emp.class,id);
thinkphp 3.2連結Oracle資料庫,查詢資料
ennnn,換工作了,開始用新的東西了,最近就是呼叫nc介面,資料庫是Oracle,首先先把資料查出來,這個比較簡單。 在網上看的其他的方法都是改資料庫配置檔案,然後需要修改tp核心的一個類檔案,比較繁瑣, 現在教你一個超級簡單的方法,不需要改任何地方,自己寫就行了 public function
Oracle資料庫中查詢結果集中保留兩位小數的問題
工作中遇到的Oracle資料庫欄位格式化問題,在此記錄 保留兩位小數主要分為兩種情況: 1.數字保留兩位小數;(小數點左側數字可能比較大,比如1234567890.12) 2.百分比保留兩位小數;(小數點左側數字數字小於等於100,比如98.76%) 現針對O
oracle 資料庫提高查詢的方法
1、選擇最有效率的表名順序 (只在基於規則的優化器中有效): ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最後的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基
使用jdbc連線ORACLE資料庫進行查詢的一個例子
五一放假了,閒來無事學習瞭解了一下JDBC,製作了一個簡單的例子。 1.首先準備資料: 首先開啟oracle 建立一張表EC_ORG_ROLE,表的欄位截圖如下 建立的語句為: CREATE TABLE "EC_ORG_ROLE" ( "ID" NU
Oracle資料庫裡面查詢字串型別的欄位不為空和為空的SQL語句:
摘要:近期專案中,在做高階查詢的時候有個條件是根據選擇的欄位,然後再選擇欄位的值為空和不為空做查詢,在寫SQL語句的時候費了很長時間,現在記錄一下,方便日後檢視: 一:查詢字串型別的欄位的值不為空的S
Oracle篇--04 Oracle SQL高階查詢、分頁查詢
1.子查詢子查詢是一條SELECT語句,但它是巢狀在其他SQL語句中的,為的是給該SQL提供資料以支援其執行操作。檢視誰的工資高於CLARK? select ename,sal from emp wh
在Oracle資料庫中查詢所有觸發器、儲存過程、檢視、表
在Oracle資料庫中查詢所有觸發器、儲存過程、檢視、表 方法一: Select object_name From user_objects Where object_type='TRIGGER'; --所有觸發器 Select object_name From user_objects Where ob
oracle資料庫SQL查詢語句練習一
1、 選擇部門30中的所有員工。 2、 列出所有辦事員(CLERK)的姓名,編號和部門編號。 3、 找出佣金高於薪金的員工。 4、 找出佣金高於薪金的60%的員工。 5、 找出部門10中所有經理(MANAGER)和部門20中所有辦事員(CLERK)的詳
Laravel框架學習(資料庫高階查詢)
1、連線查詢(join) 連線查詢指的是將兩張表或多張表關聯到一起進行查詢,獲取一個表的行與另一個表的行匹配的資料。常見的連線查詢包括內連線(等值連線)、左(外)連線、右(外)連線和交叉連線(完全連線)等。 我們將使用者表users和文章表posts關聯到一
Oracle資料庫——限定查詢,範圍查詢,NULL判斷-02
限定查詢 簡單查詢會將一張資料表之中的全部資料行進行返回,如果說現在表中的資料行過多,那麼肯定無法進行瀏覽,所以必須對顯示的資料行的返回做一個限定。 限定查詢的是在簡單查詢的基礎上增加若干個查詢的限定條件,所有的限定條件使用WHERE子句表示,此時 的語法如下 SEL
Oracle資料庫簡單查詢的流程
首先看oracle的物理體系結構圖,如下 對於上圖,簡要的五點: ①Oracle由例項和資料庫組成 ②例項是由一個開闢的共享記憶體區SGA(system global area)和一系列後臺程序組成的,其中SGA最主要被劃分為共享池(shared pool)、資料緩衝
Oracle資料庫複雜查詢
第一題:列出至少有一個員工的所有部門編號、名稱,並統計出這些部門的平均工資、最低工資、最高工資。 select * from dept; select d.deptno,d.dname,count(empno),avg(sal),min(sal),max(s
oracle的高階查詢 多表的連線
高階查詢多表的連線 普通多表連線:select ah,a.nl,a1.xm from a,a1 where a.xm=a1.xm; 此定義要明確列,如果列名兩個表均存在,前面就需要加個表名,如a.nl,如果後面不加where的話,出現的值為兩表值的數
JAVA 讓oracle資料庫模糊查詢時不區分程式碼大小寫
方法一:select * from [table] where lower(name) like lower('%val%');select * from [table] where upper(name) like upper('%val%');table:表名name:查
python資料庫-MySQL資料庫高階查詢操作(51)
一、什麼是關係? 1、分析:有這麼一組資料關於學生的資料 學號、姓名、年齡、住址、成績、學科、學科(語文、數學、英語) 我們應該怎麼去設計儲存這些資料呢? 2、先考慮第一正規化:列不可在拆分原則 這裡面學科包含了三個學科,所以學科拆分為:語文學科、數學學科、英語學科,同樣的成績也要拆分為
66 Oracle資料庫SQL開發之 高階查詢——使用線性迴歸函式
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Oracle資料庫的高階查詢(多表查詢)
外連線就是把對於連線條件不成立的記錄,也包含在最後的結果當中,如果我們用的只是等值連線的話,而要查詢的是各部門的人數,如果有一個部門沒有人,在等值連線那邊,就不會顯示出來,但我們要的是顯示所有部門的人數,就算部門沒人也要顯示。這就要用到外連線了。可以以哪一個為主表,主表中的所有欄位值都會顯示出來,而子表中欄位