按部就班學Oracle之複雜查詢(重點)

前言sql

在實際應用中常常須要執行復雜的數據統計,常常須要顯示多張表的數據,故必需要高度重視: 複雜的select語句!數據庫

1-數據分組的重要函數: max、min、avg、sum、countide

(1)查詢出全部員工中最高薪水和最低薪水者及其姓名的信息.函數

p_w_picpath

p_w_picpath

(2)查詢出全部員工的平均工資和工資總和性能

p_w_picpath

(3)計算共有多少員工測試

p_w_picpath

(4)查詢出工資最高和最低的員工的名字、工做崗位大數據

p_w_picpath

(5)查詢出工資高於平均工資的員工信息spa

p_w_picpath

(6)查詢出工資低於平均工資和入職日期在1982年12月1日以前的員工且他們的工資都上漲10%後的信息排序

p_w_picpath

2-group by 和having子句get

group by用於對查詢的結果分組統計;

having子句用於限制分組顯示結果;

(1)查詢出每一個部門的平均工資和最高工資;

p_w_picpath

(2)查詢出每一個部門的每種崗位的平均工資和最低工資;

p_w_picpath

(3)查詢出平均工資低於2000的部門號和它的平均工資.

p_w_picpath

重點總結:

對數據分組的總結:

1.分組函數只能出如今選擇列表、having、order by子句中;

2.若在select語句中同時包含有group by、having、order by則它們的順序是group byhavingorder by;(先分組à再篩選à最後排序)

3.在選擇列中若是有列、表達式和分組函數,那麼這些列和表達式必須有一個出現group by子句中,不然會出錯!

範例:

p_w_picpath

3-多表查詢(重中之重!)

多表查詢是基於兩個和兩個以上的表或視圖的查詢。

在實際應用中,查詢單個表可能不知足要求,(例如: 查詢出sales部門位置和其員工的姓名),這種狀況下須要使用到(deptno表和emp表).

(1)查詢出僱員名、僱員工資和所在部門的名字(笛卡爾積);

原則:多表查詢的條件是:至少不能少於 表的個數-1

範例:查詢出部門名(dname),員工名(ename)和薪水(sal)的信息

p_w_picpath

p_w_picpath

(2)查詢出部門號爲10的部門名、員工名和工資;

分析:

a)套路:

*由於有3個列(部門號爲10部門名、員工名和工資)因此先用3個?(問號)代替之;

*2張表使用別名;

*找出2張表「紐帶」;

*用實際列名代替3個?號。

範例:

p_w_picpath

p_w_picpath

p_w_picpath

p_w_picpath

上面把全部部門的都查詢出來,可是咱們只要 「部門號爲10」:

p_w_picpath

(3)查詢出每一個員工的姓名、工資及其工資的級別。

p_w_picpath

p_w_picpath

p_w_picpath

擴展:

(4)查詢出僱員、僱員工資及所在部門的名字,並按部門排序。

p_w_picpath

p_w_picpath

自鏈接:

是指在同一張表的鏈接查詢。

(5)查詢出某個員工的上級領導的姓名

分析:

No.1: 先看FORD –> MGR 7566(上級領導編號) –> EMPNO 7566(僱員編號) –> 僱員名字JONES

p_w_picpath

No.2: 咱們能夠把同一張表emp表當作2張表(a一、a2)!

p_w_picpath

子句查詢

*子查詢:是指嵌入在其它sql語句中的select語句,也叫嵌套查詢。

*單行子查詢:是指只返回一行數據的子查詢語句;

*多行子查詢:是指返回多行數據的子查詢。(四、5張已是很複雜了,不建議超過它!)

(6) 單行子查詢:是指只返回一行數據的子查詢語句;

範例:

查詢出與SMITH同一部門的全部員工。

p_w_picpath

(7)多行子查詢:是指返回多行數據的子查詢。(四、5張已是很複雜了,不建議超過它!)

範例:

查詢出與部門編號爲10的工做崗位相同的僱員的名字、崗位、工資、部門號

p_w_picpath

(10)在多行子查詢中使用all操做符

範例:all:含義是全部XXX!

查詢出工資比部門編號30的全部員工的工資高的員工的姓名、工資和部門編號。

註釋:查詢出來的每條記錄中的sal都應大於部門編號爲30號中的員工薪水便可!

其實只要比最高的工資高便可)!

方法1:

p_w_picpath

方法2:效率高得多 比 方法1

232250651.jpg

(11)在多行子查詢中使用any操做符

範例:any:含義是任意一個XXX!

查詢出工資比部門編號是30的任意一個員工的工資高的員工的姓名、工資和部門編號。

註釋:查詢出來的工資只要比部門編號爲30中任一個員工大(其實只要比最低的工資高便可),就能夠了!

方法1:

p_w_picpath

方法2:效率高!

p_w_picpath

(12)多列子查詢

*單行子查詢是指子查詢只返回單列單行數據;

*多行子查詢是指返回單列多行數據,都是針對單列而言的,

*多列子查詢則是指查詢返回多個列數據的子查詢語句。

範例:

查詢出與SMITH的部門和崗位徹底相同的全部僱員。

p_w_picpath

範例:難度 ★★

查詢出高於本身部門平均工資的員工的信息。

PS:

*給列起別名時,能夠 as;

*給起別名時, as.

p_w_picpath

概括:from子句中使用子查詢

當在from子句中使用子查詢時,該子查詢會被做爲一個視圖來對待,故叫內嵌視圖

當在from子句中使用子查詢時,必須給子句查詢指定別名。

(13)分頁查詢

Oracle分頁一共有3種方式:

方法:rownum分頁:

範例:

按僱員的id號升序取出 8~12這5行!

No.1步: (select * from emp )看成是內嵌視圖且起個別名a1,以下圖所示:

p_w_picpath

No.2步: 顯示rownum[Oracle分配的] (注:看成公式記住!)

p_w_picpath

註釋:

* (select * from emp) a1表示: 給(select * from emp)起個別名爲a1;

* rownum rn 表示:顯示rownum(行號)且別名是rn;

* a1.* 表示: 將子查詢(select * from emp)取出來,再查詢1次.

No.3步: 取出/篩選/截取rn列小於等於12;

p_w_picpath

//將(select a1.*,rownum rn from (select * from emp) a1 where rownum<=12)看成內嵌視圖(from子查詢),再次查詢之,以下圖所示:

p_w_picpath

概括總結:

a. 若是指定查詢列,則僅需修改最內層的子查詢; (select * from emp)

範例: 查詢出rn列,行號爲8~12的僱員姓名、薪水的信息。

p_w_picpath

b.如何排序,僅需修改最內層的子查詢;

範例:查詢出rn列,行號爲8~12的僱員姓名、薪水且按薪水的升序排列的信息。

p_w_picpath

範例:查詢出rn列,行號爲8~12的僱員姓名、薪水且按薪水的降序排列的信息。

p_w_picpath

c.查詢出4~9

p_w_picpath

PS:

統計一張表(emp)總共有多少行?

p_w_picpath

(14)用查詢結果建立新表

範例:在生產環境中,咱們不能對正在運行的表做增、刪、改、查,則可用此方法建立一張新表(testemp),再在testemp表作測試!

p_w_picpath

(15)合併查詢 注:實際工做中,用得不多!絕世高手才用!查詢速度很是快!

在實際應用中,爲了合併多個select語句的結果,可使用集合操做符unio、unio all、intersect、minus 。

1)union

用於取得2個結果集的並集。union會自動去掉結果中重複的行。

2)union all

用於取得2個結果集的並集。union all不會去掉結果中重複的行,並且不會排序。

3)intersect

用於取得2個結果集的交集

4)minus

用於取得2個結果集的差集。只顯示在第1個集合中,而不存在第2個集合中的數據。

範例:union用於取得2個結果集的並集。union會自動去掉結果中重複的行.

p_w_picpath

範例:union all用於取得2個結果集的並集。union all不會去掉結果中重複的行,並且不會排序.

p_w_picpath

範例:intersect用於取得2個結果集的交集。

p_w_picpath

範例:minus用於取得2個結果集的差集。只顯示在第1個集合中,而不存在第2個集合中的數據.

p_w_picpath

2-左、右鏈接

關於左、右鏈接指的是查詢判斷條件的參考方向,例如:有以下查詢:

071933546.jpg

部門一共有4個,可是如今只返回3個部門的信息,缺乏40部門的信息,由於在僱員表中沒有一條記錄是屬於40部門的,故如今不會顯示40部門的信息。即:如今的查詢是以emp表爲參考,若是如今我非要顯示40部門的信息呢?就必須改變參考方向,因而左、右鏈接就應運而生了!

範例:

072015204.jpg

如上圖所示:40部門出現了!故發現參考方向改變了,而「(+)」就用於左、右鏈接的更改,此種符號有如下兩種使用狀況:

* (+)= :放在了等號的左邊,表示的是右鏈接;

*=(+) : 放在了等號的右邊,表示的是左鏈接

可是不必刻意的區分是左,仍是右,只是根據查詢結果而定,若所須要的數據沒有顯示出來,就改變鏈接的方向便可。

範例:查詢出每一個僱員的姓名和領導的姓名

072657638.jpg

由上圖可知,此時的查詢的結果少了1條記錄,即缺乏了「KING」的記錄,是由於KING沒有上級領導,而想解決此問題須要使用左、右鏈接的問題了。

072825927.jpg

注:此種符號是Oracle數據庫本身獨有的,其餘數據庫不能使用!

3-SQL1999語法:

SQL語法之中,也提供了一套用於錶鏈接的操做SQL,格式以下:

072942498.jpg

分解上面的多個語法:

1、交叉鏈接(CROSS JOIN):用於產生笛卡爾積;


SQL> SELECT * FROM emp CROSS JOIN dept;

笛卡爾積自己並非屬於無用的內容,在某些狀況下仍是須要使用的。

2、天然鏈接(NATURAL JOIN):自動找到匹配的關聯字段,消除笛卡爾積;

073348508.jpg

可是並非全部的字段都是關聯字段,設置關聯字段須要經過約束指定。

3JOIN…USING子句:用戶本身指定一個消除笛卡爾積的字段;

073453117.jpg

4JOIN…ON子句:用戶本身指定一個能夠消除笛卡爾積的關聯條件;

073557493.jpg

5、鏈接方向的改變:

* ()鏈接:LEFT OUTER JOIN…ON

* ()鏈接:RIGHT OUTER JOIN…ON

* ()鏈接:FULL OUTER JOIN…ONà將兩張表中沒有的數據都顯示出來。

範例:

073703694.jpg

沒有40部門,咱們換成RIGHT JOIN…ON ,以下圖所示:

073949376.jpg

由上可知:40部門出現了!

Oracle以外的數據庫(SQLSERVERMYSQLDB2等)都使用以上的SQL1999語法操做,故必需要會!(固然,一直使用Oracle數據庫,就能夠不會:))

再次強調:多表查詢的性能確定不高,並且性能必定要在大數據量的狀況下,才能發現。

相關文章
相關標籤/搜索