1. 程式人生 > >Oracle的多種複雜查詢深入講解

Oracle的多種複雜查詢深入講解

1、多表查詢

1.1、簡介

需要從多個數據表裡取出資料,那麼就屬於多表查詢,在FROM子句後面要設定多張資料表。

1.2、語法

?

1

2

3

4

SELECT [DISTINCT] * | 列名稱 [別名],列名稱 [別名],...

FROM 表名稱[別名],表名稱[別名]

[WHERE  過濾條件(s)]

[ORDER BY 欄位 [ASC | DESC],欄位 [ASC | DESC],...];

1.3、例項

例項1、顯示每個僱員的編號、姓名、職位、工資、部門名稱、部門位置

?

1

2

3

SELECT e.empno,e.ename,e.job,e.sal,d.dame,d.loc

FROM emp e, dept d

WHERE e.deptno=d.deptno;

例項2、查詢每個僱員的編號、姓名、職位、工資、工資等級、部門名稱

?

1

2

3

SELECT e.empno,e.ename,e.job,e.sal,s.grade,d.dname

FROM emp e,salgrade s,dept d

WHERE e.sal

BETWEEN losal AND hisal AND e.deptno=d.deptno;

1.4、表的連線方式

1.4.1 內連線

1、等值連線

在連線條件中使用等於號(=)運算子比較被連線列的列值,其查詢結果中列出被連線表中的所有列,包括其中的重複列

例項1、查詢部門編號為30的員工編號、姓名、部門名稱

?

1

2

3

SELECT e.empno, e.ename, d.dname

FROM emp e, dept d

WHERE e.deptno = d.deptno and e.deptno = 30;

2、非等值連線在連線條件使用除等於運算子以外的其它比較運算子比較被連線的列的列值。這些運算子包括>、>=、<=、<、!>、!<和<>
例項1、查詢工資為1500以上的員工所屬部門和所在的具體地點

?

1

2

3

SELECT DISTINCT d.dname, d.loc

FROM emp e, dept d

WHERE e.deptno = d.deptno and e.sal >1500;

3、自然連線

在連線條件中使用等於(=)運算子比較被連線列的列值,但它使用選擇列表指出查詢結果集合中所包括的列,並刪除連線表中的重複列。簡言之,基於兩個表的同名的一個或多個列

【注意】自然連線是根據兩個表中同名的列而進行連線的,當列不同名時,自然連線將失去意義

例項1、查詢所有員工的員工編號、員工姓名、部門編號、部門名稱

?

1

2

Select e.empno, e.ename, e.deptno, d.dname

From emp e NATURAL JOIN dept d;

1.4.2 外連線

用於檢索一個表的所有記錄和另一個表中的匹配行。

(+)號的作用:+號可以理解為補充的意思,加在那個表的列上就代表這個表的列為補充。加在右表的列上代表右表為補充,為左連線。加在左表的列上代表左表為補充,為右連線。注意:完全外連線中不能使用+號。(+)為Oracle特有。

建立兩張實驗表

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

CREATE TABLE t_A ( 

id   number, 

name  VARCHAR2(10) 

); 

CREATE TABLE t_B ( 

id   number, 

name  VARCHAR2(10) 

); 

INSERT INTO t_A VALUES(1,'A'); 

INSERT INTO t_A VALUES(2,'B'); 

INSERT INTO t_A VALUES(3,'C'); 

INSERT INTO t_A VALUES(4,'D'); 

INSERT INTO t_A VALUES(5,'E'); 

INSERT INTO t_B VALUES(1,'AA'); 

INSERT INTO t_B VALUES(1,'BB'); 

INSERT INTO t_B VALUES(2,'CC'); 

INSERT INTO t_B VALUES(1,'DD'); 

INSERT INTO t_B VALUES(7,'GG');

1、左外連線

左外連線就是在結果中除了滿足連線條件之外的行,還包括LEFT OUTER JOIN左側表的所有行。

程式碼實現

?

1

2

3

SELECT *

FROM t_a a,t_b b

WHERE a.id=b.id(+);

\

2、右外連線

與左外連線同理,無限滿足右表,即根據右表中資料去左表搜尋,如果沒有匹配資料,填入null

程式碼實現

?

1

2

3

SELECT *

FROM t_a a,t_b b

WHERE a.id(+)=b.id;

\

3、全連線

左右表都不加限制。即右外連線的結果為:左右表匹配的資料+左表沒有匹配到的資料+右表沒有匹配到的資料

程式碼實現

?

1

2

SELECT *

FROM t_a a FULL JOIN t_b b on a.id=b.id;

\

4、關於內外連線圖解
載入中...

1.4.3 交叉連線

交叉連線不帶WHERE子句,它返回被連線的兩個表所有資料行的笛卡爾積,返回結果集合中的資料行數等於第一個表中符合查詢條件的資料行數乘以第二個表中符合查詢條件的資料行數。

例項1、求emp表和dept表的笛卡爾積

?

1

2

SELECT *

FROM emp, dept;

1.4.4 自連線

自連線(self join)是SQL語句中經常要用的連線方式,使用自連線可以將自身表的一個映象當作另一個表來對待,從而能夠得到一些特殊的資料。

例項1、顯示所有員工的上級領導的姓名

?

1

2

3

SELECT worker.ename, boss.ename

FROM emp worker, emp boss

WHERE worker.mgr = boss.empno;

2、統計查詢

2.1、簡介

需要使用統計函式的查詢稱為統計查詢

2.1.1 常用的統計函式

統計個數:COUNT(*|[DISTINCT]欄位)、最值:(MAX(欄位)、MIN(欄位))、求和:SUM(數字欄位)、求平均:AVG(數字欄位)

2.2、語法

?

1

2

3

4

SELECT [DISTINCT] 分組欄位 [別名],... | 統計函式

FROM 表名稱[別名]

[WHERE  過濾條件(s)]

[ORDER BY 欄位 [ASC|DESC]];

2.3、例項

例項1、查詢所有僱員之中最高和最低工資

?

1

2

SELECT MAX(sal),MIN(sal)

FROM emp;

例項2、統計出所有僱員的總工資以及平均工資

?

1

2

SELECT SUM(sal),AVG(sal)

FROM emp;

2.4、分組統計查詢

2.4.1 語法

?

1

2

3

4

5

SELECT [DISTINCT] 分組欄位 [別名],... | 統計函式

FROM 表名稱[別名]

[WHERE  過濾條件(s)]

[GROUP BY 分組欄位,分組欄位,分組欄位,...]

[ORDER BY 欄位 [ASC|DESC]];

2.4.2 例項

例項1、按照職位分組,統計出每個職位的名稱、人數、平均工資

?

1

2

3

SELECT job,COUNT(*),AVG(sal)

FROM emp

GROUP BY job;

例項2、查詢每個部門的名稱、人數、平均工資

?

1

2

3

4

SELECT d.dname,COUNT(e.empno),AVG(e.sal)

FROM emp e,dept d

WHERE e.deptno(+)=d.deptno

GROUP BY d.dname;

例項3、查詢出平均工資高於2000的職位名稱以及平均工資。

?

1

2

3

4

SELECT job,AVG(sal)

FROM emp

GROUP BY job

HAVING AVG(sal)>2000;

2.4.3關於WHERE與HAVING的區別

WHERE發生在GROUP BY操作之前,屬於分組前的資料篩選,即:從所有的資料之中篩選出可以分組的資料,WHERE子句不允許使用統計函式;

HAVING發生在GROUP BY操作之後,是針對於分組後的資料進行篩選,HAVING子句可以使用統計函式;

3、子查詢

3.1、簡介

當一個查詢是另一個查詢的條件時,稱之為子查詢。

3.2、語法

?

1

2

3

4

5

6

SELECT [DISTINCT] * | 列名稱 [別名],列名稱 [別名],...

FROM 表名稱[別名]

[WHERE  過濾條件(SELECT [DISTINCT] * | 列名稱 [別名],列名稱 [別名],...

FROM 表名稱[別名]

[WHERE  過濾條件(s)]

)]

3.3、分類

單行子查詢、多行子查詢、多列子查詢、做為from字句的子查詢(內嵌檢視查詢)

3.3.1單行子查詢

單行子查詢是指只返回一行資料的子查詢語句
例項顯示與SMITH同部門的所有員工

?

1

2

3

4

5

SELECT *

FROM emp

WHERE deptno = (SELECT deptno

FROM emp

WHERE ename = 'SMITH');

3.3.2 多行子查詢

多行子查詢指返回多行資料的子查詢
例項查詢和部門10的工作相同的僱員的名字、崗位、工資、部門號

?

1

2

3

4

5

SELECT ename, job, sal, deptno

FROM emp

WHERE job IN(SELECT DISTINCT job

FROM emp

WHERE deptno = 10);

1、在多行子查詢中使用all操作符

例項顯示工資比部門30的所有員工的工資高的員工的姓名、工資和部門號

?

1

2

3

4

5

SELECT ename, sal, deptno

FROM emp

WHERE sal > ALL(SELECT sal

FROM emp

WHERE deptno = 30);

方法二 使用聚合函式,(執行效率最高)

?

1

2

3

4

5

SELECT ename, sal, deptno

FROM emp

WHERE sal > (SELCT MAX(sal)

FROM emp

WHERE deptno = 30);

2、在多行子查詢中使用any操作符

例項顯示工資比部門30的任意一個員工的工資高的員工姓名、工資和部門號

?

1

2

3

4

5

SELECT ename, sal, deptno

FROM emp

WHERE sal > ANY (SELECT sal

FROM emp

WHERE deptno = 30);

方法二使用聚合函式,(執行效率最高)

?

1

2

3

4

5

SELECT ename, sal, deptno

FROM emp

WHERE sal > (SELECT MIN(sal)

FROM emp

WHERE deptno = 30);

3.3.3 多列子查詢

多列子查詢是指查詢返回多個列資料的子查詢語句
例項查詢與SMITH 的部門和崗位完全相同的所有僱員

?

1

2

3

4

5

SELECT *

FROM emp

WHERE(deptno, job) =(SELECT deptno, job

FROM emp

WHERE ename='SMITH');

3.3.4內嵌檢視查詢查詢

當在from子句中使用子查詢時,該子查詢會被作為一個檢視來對待,因此叫做內嵌檢視,當在from 子句中使用子查詢時,必須給子查詢指定別名(不能使用as關鍵字)
例項 顯示高於自己部門平均工資的員工的資訊

?

1

2

3

SELECT e.ename, e.sal, e.deptno,temp.avgsal

FROM emp e, (SELECT deptno, AVG(sal) avgsal FROM emp GROUP BY deptno) temp

WHERE e.deptno = temp.deptno AND e.sal >temp.avgsal;

4、集合操作(交、並、差)

為了合併多個select語句的結果,可以使用集合操作符號union(並集),union all(與union相似,但是它不會取消重複行,而且不會排序),intersect(交集),minus(差集)。多用於資料量比較大的資料局庫,執行速度快。
例項1、 查詢工資在2500以上或工作是經理的員工的姓名、工資、工作

?

1

2

3

4

5

SELECT ename, sal, job

FROM emp

WHERE sal >2500 UNION SELECT ename, sal, job

ROM emp

WHERE job = 'MANAGER';

例項2、 查詢工資在2500以上且工作是經理的員工的姓名、工資、工作

?

1

2

3

4

5

SELECT ename, sal, job

FROM emp

WHERE sal >2500 INTERSECT SELECT ename, sal, job

ROM emp

WHERE job = 'MANAGER';

例項3、 查詢工資在2500以上且工作不是經理的員工的姓名、工資、工作

?

1

2

3

4

5

SELECT ename, sal, job

FROM emp

WHERE sal >2500 MINUS SELECT ename, sal, job

ROM emp

WHERE job = 'MANAGER';

5、偽列

5.1、簡介

偽列就像Oracle中的一個表列,但實際上它並未儲存在表中。偽列可以從表中查詢,但是不能插入、更新或刪除它們的值。

常用的偽列:rowid和rownum。

5.2 、rowid

ROWID是一種資料型別,它使用基於64為編碼的18個字元來唯一標識一條記錄物理位置的一個ID,類似於Java中一個物件的雜湊碼,都是為了唯一標識對應物件的物理位置,需要注意的是ROWID雖然可以在表中進行查詢,但是其值並未儲存在表中,所以不支援增刪改操作

例項一、 觀察rowid 和 rownum

?

1

2

3

SELECT ROWNUM,ROWID,empno,ename,job

FROM emp

WHERE ROWNUM <= 5;

\
ROWID 的組成分析

資料物件編號

檔案編號

塊編號

行編號

OOOOOO

FFF

BBBBBB

RRR

可以用ROWID用來唯一標識表中資料(實體地址唯一)

應用 可以用來刪除表中重複資料

?

1

2

DELETE FROM 表名 WHERE ROWID NOT IN( SELECT MIN(ROWID)

FROM表名GROUP BY DEPTNO);

5.3、rownum

在查詢的結果集中,ROWNUM為結果集中每一行標識一個行號,第一行返回1,第二行返回2,以此類推。通過ROWNUM偽列可以限制查詢結果集中返回的行數。

ROWNUM與ROWID不同,ROWID是插入記錄時生成,ROWNUM是查詢資料時生成。ROWID標識的是行的實體地址。ROWNUM標識的是查詢結果中的行的次序。

例項1、 查詢前5名員工的姓名,工作,工資

?

1

2

3

SELECT ROWNUM rn,ename, job, sal

FROM emp

WHERE rn<=5;

例項2、查詢5~10號員工的姓名,工作,工資

?

1

2

SELECT * FROM (SELECT ROWNUM rn, ename,job, sal FROM emp)

WHERE rn > 5 AND rn <= 10;

\

相關推薦

Oracle多種複雜查詢深入講解

1、多表查詢 1.1、簡介 需要從多個數據表裡取出資料,那麼就屬於多表查詢,在FROM子句後面要設定多張資料表。 1.2、語法 ? 1 2 3 4 SELECT [DISTINCT] * | 列名稱 [別名],列

Oracle複雜查詢

例項1:列出薪資高於在部門30工作的所有員工的薪資的員工姓名和薪資,部門名稱,部門人數。 -emp 表:姓名,薪資,部門人數; -dept 表:部門名稱; 第一步:找出30部門的所有僱員的工資,返回多行單列; select sal from em

Oracle資料庫複雜查詢

第一題:列出至少有一個員工的所有部門編號、名稱,並統計出這些部門的平均工資、最低工資、最高工資。 select * from dept; select d.deptno,d.dname,count(empno),avg(sal),min(sal),max(s

oracle複雜查詢(一)

1、 列出至少有一個員工的所有部門編號、名稱,並統計出這些部門的平均工資、最低工資、最高工資。 select d.DEPTNO 部門編號,d.DNAME 部門名稱,trunc(avg(e.SAL)) 平均薪資, min(e.SAL) 最低工資, max(e.SAL) 最高工資 from emp e, DE

(ORACLE)PL/SQL 表的複雜查詢

表的複雜查詢 在實際應用中,常常需要執行復雜的資料統計,經常需要顯示多張表的資料現在我們來學習比較複雜的select的語句。我們將繼續使用scott使用者下emp表作為示例。 聚合函式 MAX函式: 對一列取最大值 MIN函式: 對一列取最小值 AVG函式: 對一列取平均值 SU

深入講解MongoDB的慢日誌查詢(profile)

  https://www.jb51.net/article/117441.htm   前言 說到MongoDB的慢日誌分析,就不得不提到profile分析器,profile分析器將記錄的慢日誌寫到system.profile集合下,這個集合是一個固定集合。我們可

Oracle學習筆記 深入剖析事務槽及Oracle多種提交方式

Oracle 學習筆記 深入剖析事務槽及Oracle多種提交方式 這節課把事務槽和oracle事務的提交方式講一下 講完以後再去回顧上節課講的oracle的undo裡面的事務的整個操作過程的時候大家就更清晰了 一)事務槽數量引數 每一個orac

Oracle複雜查詢

現有一EMP(員工表),結構如下: empno:員工id,deptno:部門id,sal:工資,name:員工姓名 要求:查詢出每個部門大於該部門平均工資的人數。 SELECT deptno, C

Oracle學習之路(二):oracle多表查詢+分組查詢+子查詢講解與案例分析+經典練習題

1.笛卡爾集和叉集 笛卡爾集會在下面條件下產生:省略連線條件、連線條件無效、所有表中的所有行互相連線。 為了避免笛卡爾集, 可以在 WHERE 加入有效的連線條件。在實際執行環境下,應避免使用全笛卡爾集。 使用CROSS JOIN 子句使連線的表產生叉集。叉集和笛卡

Oracle遞歸查詢的原理

turn mes span msu mit from ams evel ims 在Oracle 10g下。來到scott用戶下。分別以層次 1,2,3,4上的節點做實驗: 當start with是根節點(level=1),要查其子節點,connect

Day16 Django深入講解

.html .com log 深入 cnblogs javascrip nbsp 多線程 script 參考博客: http://www.cnblogs.com/yuanchenqi/articles/6083427.html http://www.cnblogs.com/

ORACLE遞歸查詢

data- csdn ins 方式 也有 ren tracking char 其它 ORACLE支持常規的用CTE遞歸的方式實現遞歸查詢,也有自己特有的查詢方式,ORACLE文檔中叫層次數據查詢。 這裏通過一個簡單的樣例來介紹這兩種查詢方式。 數據準備: CREATE

oracle閃回查詢和閃回數據庫

數據庫技術 oracle 回收站 system start oracle閃回查詢和閃回數據庫 區別:數據閃回查詢,只需要啟用撤銷表空間自動管理回滾信息。使用閃回刪除技術和閃回數據庫技術,需要啟動回收站,閃回恢復區。(歸檔模式使用) 具體設置:---cmd sqlplus

Oracle鎖表查詢和解鎖方法

數據庫查詢 lar 關系 鎖級別 share 技術 獲取 suse b2c 數據庫操作語句的分類 DDL:數據庫模式定義語言,關鍵字:create DML:數據操縱語言,關鍵字:Insert、delete、update DCL:數據庫控制語言 ,關鍵字:grant

Oracle中如何查詢CLOB字段類型的內容

查詢 lob dbm -s 案例 類型 數據 ear 使用 語法:select * from table_name where dbms_lob.instr(字段名(clod類型),‘查詢條件‘,1,1) > 0; 語法解釋:在Oracle中,可以使用inst

oracle表空間查詢維護命令大全之中的一個(數據表空間)史上最全

ava 劃分 man max rac 帳戶 oca nio msi 表空間是數據庫的邏輯劃分,一個表空間僅僅能屬於一個數據庫。全部的數據庫對象都存放在建立指定的表空間中。但主要存放的是表, 所以稱作表空間。在oracle 數據庫中至少存在

大數據oracle分頁查詢

增加 返回 and 一個 data 連接 相等 查詢條件 重復數 ROWNUM 可能都知道ROWNUM只適用於小於或小於等於,如果進行等於判斷,那麽只能等於1,不能進行大於的比較。 ROWNUM是oracle系統順序分配為從查詢返回的行的編號,返回的第一行分配的是

Oracle 部門員工查詢

sts cot analyst account tin int war 薪資 class --部門:部門編號,部門名稱,地址; --員工:員工編號,員工名字,職務,管理編號,入職日期,薪資,獎金,部門編號; CREATE TABLE dept( dept

[轉抄]oracle單表查詢去重(效率比較高的一種方式)

sel select 單表查詢 效率 查詢 rownum 說明 acl 分組 1 select 2 * 3 from 4 ( 5 select 6 a.*, rownum r_n 7

Oracle 高級查詢1 關聯查詢 分組查詢

null 函數 定義 關聯 group 顯示 tinc 查詢 求平均值 高級查詢 1.關聯查詢作用:可以跨越多表查詢 --查詢出員工的名字和他所在部門的的名字 語法:select 列,列,列 from 表1 join 表2on 表1外鍵=表2主鍵 2.外聯接 左外聯