前言sql
在實際應用中常常須要執行復雜的數據統計,常常須要顯示多張表的數據,故必需要高度重視: 複雜的select語句!數據庫
1-數據分組的重要函數: max、min、avg、sum、countide
(1)查詢出全部員工中最高薪水和最低薪水者及其姓名的信息.函數
(2)查詢出全部員工的平均工資和工資總和性能
(3)計算共有多少員工測試
(4)查詢出工資最高和最低的員工的名字、工做崗位大數據
(5)查詢出工資高於平均工資的員工信息spa
(6)查詢出工資低於平均工資和入職日期在1982年12月1日以前的員工且他們的工資都上漲10%後的信息排序
2-group by 和having子句get
group by用於對查詢的結果分組統計;
having子句用於限制分組顯示結果;
(1)查詢出每一個部門的平均工資和最高工資;
(2)查詢出每一個部門的每種崗位的平均工資和最低工資;
(3)查詢出平均工資低於2000的部門號和它的平均工資.
重點總結:
對數據分組的總結:
1.分組函數只能出如今選擇列表、having、order by子句中;
2.若在select語句中同時包含有group by、having、order by則它們的順序是group by、having、order by;(先分組à再篩選à最後排序)
3.在選擇列中若是有列、表達式和分組函數,那麼這些列和表達式必須有一個出現在group by子句中,不然會出錯!
範例:
3-多表查詢(重中之重!)
多表查詢是基於兩個和兩個以上的表或視圖的查詢。
在實際應用中,查詢單個表可能不知足要求,(例如: 查詢出sales部門位置和其員工的姓名),這種狀況下須要使用到(deptno表和emp表).
(1)查詢出僱員名、僱員工資和所在部門的名字(笛卡爾積);
原則:多表查詢的條件是:至少不能少於 表的個數-1
範例:查詢出部門名(dname),員工名(ename)和薪水(sal)的信息
(2)查詢出部門號爲10的部門名、員工名和工資;
分析:
a)套路:
*由於有3個列(部門號爲10部門名、員工名和工資)因此先用3個?(問號)代替之;
*2張表使用別名;
*找出2張表「紐帶」;
*用實際列名代替3個?號。
範例:
上面把全部部門的都查詢出來,可是咱們只要 「部門號爲10」:
(3)查詢出每一個員工的姓名、工資及其工資的級別。
擴展:
(4)查詢出僱員、僱員工資及所在部門的名字,並按部門排序。
自鏈接:
是指在同一張表的鏈接查詢。
(5)查詢出某個員工的上級領導的姓名
分析:
No.1: 先看FORD –> MGR 7566(上級領導編號) –> EMPNO 7566(僱員編號) –> 僱員名字JONES
No.2: 咱們能夠把同一張表emp表當作2張表(a一、a2)!
子句查詢
*子查詢:是指嵌入在其它sql語句中的select語句,也叫嵌套查詢。
*單行子查詢:是指只返回一行數據的子查詢語句;
*多行子查詢:是指返回多行數據的子查詢。(四、5張已是很複雜了,不建議超過它!)
(6) 單行子查詢:是指只返回一行數據的子查詢語句;
範例:
查詢出與SMITH同一部門的全部員工。
(7)多行子查詢:是指返回多行數據的子查詢。(四、5張已是很複雜了,不建議超過它!)
範例:
查詢出與部門編號爲10的工做崗位相同的僱員的名字、崗位、工資、部門號
(10)在多行子查詢中使用all操做符
範例:all:含義是全部XXX!
查詢出工資比部門編號30的全部員工的工資高的員工的姓名、工資和部門編號。
註釋:查詢出來的每條記錄中的sal都應大於部門編號爲30號中的員工薪水便可!
(其實只要比最高的工資高便可)!
方法1:
方法2:效率高得多 比 方法1
(11)在多行子查詢中使用any操做符
範例:any:含義是任意一個XXX!
查詢出工資比部門編號是30的任意一個員工的工資高的員工的姓名、工資和部門編號。
註釋:查詢出來的工資只要比部門編號爲30中任一個員工大(其實只要比最低的工資高便可),就能夠了!
方法1:
方法2:效率高!
(12)多列子查詢
*單行子查詢是指子查詢只返回單列、單行數據;
*多行子查詢是指返回單列多行數據,都是針對單列而言的,
*多列子查詢則是指查詢返回多個列數據的子查詢語句。
範例:
查詢出與SMITH的部門和崗位徹底相同的全部僱員。
範例:難度 ★★
查詢出高於本身部門平均工資的員工的信息。
PS:
*給列起別名時,能夠加 as;
*給表起別名時,不能加 as.
概括:在from子句中使用子查詢
當在from子句中使用子查詢時,該子查詢會被做爲一個視圖來對待,故叫內嵌視圖;
當在from子句中使用子查詢時,必須給子句查詢指定別名。
(13)分頁查詢
Oracle分頁一共有3種方式:
方法:rownum分頁:
範例:
按僱員的id號升序取出 8~12這5行!
No.1步: 將(select * from emp )看成是內嵌視圖且起個別名a1,以下圖所示:
No.2步: 顯示rownum[Oracle分配的] (注:看成公式記住!)
註釋:
* (select * from emp) a1表示: 給(select * from emp)起個別名爲a1;
* rownum rn 表示:顯示rownum(行號)且別名是rn;
* a1.* 表示: 將子查詢(select * from emp)取出來,再查詢1次.
No.3步: 取出/篩選/截取rn列小於等於12;
//將(select a1.*,rownum rn from (select * from emp) a1 where rownum<=12)看成內嵌視圖(from子查詢),再次查詢之,以下圖所示:
概括總結:
a. 若是指定查詢列,則僅需修改最內層的子查詢; (select * from emp)
範例: 查詢出rn列,行號爲8~12的僱員姓名、薪水的信息。
b.如何排序,僅需修改最內層的子查詢;
範例:查詢出rn列,行號爲8~12的僱員姓名、薪水且按薪水的升序排列的信息。
範例:查詢出rn列,行號爲8~12的僱員姓名、薪水且按薪水的降序排列的信息。
c.查詢出4~9
PS:
統計一張表(emp)總共有多少行?
(14)用查詢結果建立新表
範例:在生產環境中,咱們不能對正在運行的表做增、刪、改、查,則可用此方法建立一張新表(testemp),再在testemp表作測試!
(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會自動去掉結果中重複的行.
範例:union all用於取得2個結果集的並集。union all不會去掉結果中重複的行,並且不會排序.
範例:intersect用於取得2個結果集的交集。
範例:minus用於取得2個結果集的差集。只顯示在第1個集合中,而不存在第2個集合中的數據.
2-左、右鏈接
關於左、右鏈接指的是查詢判斷條件的參考方向,例如:有以下查詢:
部門一共有4個,可是如今只返回3個部門的信息,缺乏40部門的信息,由於在僱員表中沒有一條記錄是屬於40部門的,故如今不會顯示40部門的信息。即:如今的查詢是以emp表爲參考,若是如今我非要顯示40部門的信息呢?就必須改變參考方向,因而左、右鏈接就應運而生了!
範例:
如上圖所示:40部門出現了!故發現參考方向改變了,而「(+)」就用於左、右鏈接的更改,此種符號有如下兩種使用狀況:
* (+)= :放在了等號的左邊,表示的是右鏈接;
*=(+) : 放在了等號的右邊,表示的是左鏈接。
可是不必刻意的區分是左,仍是右,只是根據查詢結果而定,若所須要的數據沒有顯示出來,就改變鏈接的方向便可。
範例:查詢出每一個僱員的姓名和領導的姓名
由上圖可知,此時的查詢的結果少了1條記錄,即缺乏了「KING」的記錄,是由於KING沒有上級領導,而想解決此問題須要使用左、右鏈接的問題了。
注:此種符號是Oracle數據庫本身獨有的,其餘數據庫不能使用!
3-SQL:1999語法:
在SQL語法之中,也提供了一套用於錶鏈接的操做SQL,格式以下:
分解上面的多個語法:
1、交叉鏈接(CROSS JOIN):用於產生笛卡爾積;
SQL> SELECT * FROM emp CROSS JOIN dept;
笛卡爾積自己並非屬於無用的內容,在某些狀況下仍是須要使用的。
2、天然鏈接(NATURAL JOIN):自動找到匹配的關聯字段,消除笛卡爾積;
可是並非全部的字段都是關聯字段,設置關聯字段須要經過約束指定。
3、JOIN…USING子句:用戶本身指定一個消除笛卡爾積的字段;
4、JOIN…ON子句:用戶本身指定一個能夠消除笛卡爾積的關聯條件;
5、鏈接方向的改變:
* 左(外)鏈接:LEFT OUTER JOIN…ON;
* 右(外)鏈接:RIGHT OUTER JOIN…ON;
* 全(外)鏈接:FULL OUTER JOIN…ON;à將兩張表中沒有的數據都顯示出來。
範例:
沒有40部門,咱們換成RIGHT JOIN…ON ,以下圖所示:
由上可知:40部門出現了!
在Oracle以外的數據庫(SQLSERVER、MYSQL、DB2等)都使用以上的SQL:1999語法操做,故必需要會!(固然,一直使用Oracle數據庫,就能夠不會:))
再次強調:多表查詢的性能確定不高,並且性能必定要在大數據量的狀況下,才能發現。