目錄
1. 子查詢
1.1 單行子查詢
1.2 多行子查詢
1.3 多列子查詢
1.4 在 from 子句中使用子查詢
2. 多表查詢
3. 自連接?
4. 合并查詢
4.1 union
4.2 union all
5. 表的內連接
6. 表的外連接
????????下列先給出該博客中所用到的所有表的數據。
? ? ? ? (1)部門表(dept)
? ? ? ? (2)?員工表(emp)
? ? ? ? (3)?薪資等級表(salgrade)
1. 子查詢
? ? ? ? 子查詢是指嵌入在其他 sql 語句中的 select 語句,也叫嵌套查詢。
1.1 單行子查詢
? ? ? ? 單行子查詢:指的是在子查詢語句中,返回的數據只有一行。-- 返回一個字段并且該字段只有一個值。
? ? ? ? 例1:查詢與 SMITH 同一個部門的員工。
? ? ? ? 如上圖,MySQL 會先執行括號中的子語句,返回一個 ename = 'SMITH' 的部門號 deptno,然后再執行外部 select 語句,篩選部門號與 SMITH 相同的數據。?
1.2 多行子查詢
? ? ? ? 多行子查詢:指的是在子查詢語句中,返回的數據為多行。-- 返回一個字段并且該字段有多個值。
? ? ? ? (1)in 關鍵字:用于判斷一個數據是否在某一個集合當中。
? ? ? ? 例1:查詢和 10 號部門的工作崗位相同的員工名字,崗位,工資,部門號但是不包含 10 號部門自己的員工。
? ? ? ? 上述的查詢可以這樣理解,(1)查出 10 號部門有哪些崗位。(2)篩選出 emp 表中與 10 部門中崗位相同崗位的員工。(3)排除 10 號部門自己的員工。?
? ? ? ? 上述的語句中,子查詢到的 job 不只是一個值,所以被稱為多行子查詢。
? ? ? ? (2)all 關鍵字:用于在判斷的時候所有數據都要滿足條件。
? ? ? ? 例2:查詢工資比 30 號部門所有員工的工資高的員工的姓名、工資和部門號。
? ? ? ? 上圖中的做法是先找到 30 號部門中最高的工資,然后再篩選出大于最高工資的員工。
? ? ? ? 而上述的做法是先篩選出 30 號部門中所有員工的工資,然后再次篩選大于 30 號部門中所有員工工資的其他員工。?
? ? ? ? (3)any 關鍵字:用于在判斷時是否至少有一條數據滿足條件。
? ? ? ? 例3:顯示工資比 30 號部門中至少一名員工工資高的員工的姓名、工資、和部門號(包含自己部門的員工)。
? ? ? ? 換句話說,就是顯示比 30 號部門中最低工資要高的員工。
? ? ? ? 上圖為先篩選出 30 號部門中最低工資,然后篩選大于最低工資的員工。
? ? ? ? 而這個圖是先篩選出 30 號部門所有員工的工資,然后判斷的時候表示 sal 大于 30 號部門中任意一名員工的工資高即可。?
1.3 多列子查詢
? ? ? ? 多列子查詢:子查詢中返回的數據為多列。-- 返回多個字段,該字段可以有一個值也可以有多個值。其實上述例子中的情況為單列單行自查徐,單列多行子查詢,所以多行和多列是不沖突的。
? ? ? ? 例1:查詢和 SMITH 的部門和崗位完全相同的其他員工。
? ? ? ? 上述的子查詢可以稱為多列單行子查詢,先查出 SMITH 的部門號和崗位,在利用部門號和崗位篩選出員工,最后在篩選掉 SMITH 自己。?
1.4 在 from 子句中使用子查詢
? ? ? ? 上述所有的子查詢都是在 where 子句中充當篩選條件。但是子查詢也可以在 from 子句中使用,這里要清楚一個概念,任何時刻查詢出來的臨時數據,在邏輯上本質都可以當作一張表。
? ? ? ? 例1:顯示每個部門中高于該部門平均工資的員工的姓名、部門、工資以及部門平均工資。
? ? ? ? 上圖中先是將每個部門的部門號和部門平均工資篩選出來作為一張臨時表,再將兩張表作笛卡爾積,篩選出兩張表中部門號相同且工資大于部門平均工資的員工信息。?
2. 多表查詢
? ? ? ? 如下圖所示,得到的結果稱為笛卡爾積,也就是兩張表每條數據的兩兩組合:
? ? ? ? 其中有些數據是沒有意義的,比如第一條數據,SMITH 是屬于 20 號部門的,所有拼接上部門表中部門號為 10 的數據就不是一條合理的數據,可以利用兩張表相同的字段(上圖中的部門號)進行有意義的數據篩選:
? ? ? ? 例1:顯示員工名、員工工資以及所在部門(不僅僅是部門號,還有部門信息)。則需要從 emp 表和 dept 表中得出數據,所以可以用以下查詢語句進行查詢:
? ? ? ? 例2:顯示各個員工的姓名、工資及工資級別。則需要從 emp 表和 salgrade 表中得到數據,可以通過員工工資在那個工資等級的范圍內進行有效數據的篩選:
3. 自連接?
? ? ? ? 自連接就是將兩張相同的表作笛卡爾積。由于兩張表的名字相同,所以作笛卡爾積的時候需要進行重命名。
? ? ? ? 如上兩張圖所示,當沒有重命名對相同的表作笛卡爾積會報錯,重命名之后作笛卡爾積就不會報錯。?
? ? ? ? 例1:顯示員工 FORD 上級領導的編號和姓名(mgr 是員工領導的編號)。這個需求可以分為兩步來進行,一是找打 FORD 上級領導的編號,二是使用這個編號找到領導的信息,而這些信息都在 emp 表中,所以語句如下:
? ? ? ? 也可以將 emp 表先進行自連接,然后通過 FORD 上級領導編號 mgr 和員工編號 empno 相等的方式找到 FORD 上級領導的信息,語句如下:
4. 合并查詢
4.1 union
? ? ? ? union:該操作符用于取得兩個結果集的并集。當使用該操作符時,會自動去掉結果集中重復的行。
? ? ? ? 例1:將工資大于 2500 或職位是 MANAGER 的人找出來。
? ? ? ? 上述是使用了兩個篩選條件篩選出結果。?
? ? ? ? 而上圖是使用 union 將兩個查詢的結果集合并起來。?
4.2 union all
? ? ? ? union all:該操作符用于取得兩個結果集的并集。但是該操作符不對結果集中重復行去重。
? ? ? ? 上述兩種合并查詢的時候列字段的個數和屬性必須相同才能進行拼接。?
5. 表的內連接
? ? ? ? 上述多表進行笛卡爾積之后都需要一個 where 語句進行有效數據的篩選,其實就叫做內連接,但是為了方便給其規定了一種內連接語法:
select 字段 from 表1 inner join 表2 on 連接條件 and 其他條件;
? ? ? ? 例1:顯示 SMITH 的名字和部門名稱。
? ? ? ? 上圖為之前使用 where 子句的寫法。
? ? ? ? 這個是使用內連接語法的寫法。?
6. 表的外連接
? ? ? ? (1)左外連接:在兩張表進行笛卡爾積之后,左表的數據完全顯示。
select 字段 from 表名1 left join 表名2 ?on 連接條件;
? ? ? ? 如上圖所示,現在有兩張表,一個學生表,一個成績表,需要將學生表中的所有行數據篩選出來,就算學生沒有成績也需要篩選出來,這時候就可以使用左外連接。
? ? ? ? (2)右外連接:?在兩張表進行笛卡爾積之后,右表的數據完全顯示。
select 字段 from 表名1 right join 表名2 ?on 連接條件;
? ? ? ? 現在需要將成績表中所有行數據篩選出來,就算成績沒有對應的學生也要將右表的所有行進行顯示。