# Ch02 集合運算與巢狀查詢 ## 01_集合運算查詢 * 集合運算子 1. **交集**(Intersection)<SQL Server有支援,但MySQL沒有> 2. **聯集**(Union) 3. **差集**(Difference)<SQL Server有支援,但MySQL沒有> * <font color="#f00">**條件**</font> : (1)兩資料表的**資料行(欄位)個數必須相同** (2)相對應的資料行(欄位)之**資料型態必須一致** ### 交集 * 兩個關聯式中**都有出現**的值組(記錄)組合在一起成為新的關聯式 ```sql= SELECT * FROM 關聯表R1 Intersect 關聯表R2 ``` ![](https://i.imgur.com/EjXYn1X.png) ### 聯集 * 新的關聯表R3中的記錄為原來**兩關聯表的所有記錄**,若有**重複的記錄**,則只會**出現一次**。 ```sql= SELECT * FROM 關聯表R1 Union 關聯表R2 ``` ![](https://i.imgur.com/c0ZPWBp.png) ### 差集 * 一個關聯表R1中的記錄**減去另一個關聯表**R2的記錄,形成新的關聯表R3的記錄。 ```sql= SELECT * FROM 關聯表R1 Except 關聯表R2 ``` ![](https://i.imgur.com/XeYzfSz.png) ## 02_巢狀查詢和子查詢 * <font color="#f00">**定義**</font> :在SELECT敘述中,再**嵌入另一個SELECT敘述**,稱為巢狀查詢。 * <font color="#f00">**介紹**</font> : **外部**的SELECT敘述稱為**主查詢**,**內嵌**的SELECT敘述為**子查詢**。 * 子查詢可以出現在: ◆ Where子句中,作為篩選條件。 ◆ From子句中,作為一個臨時表使用。 ◆ Select list中,作為一個字段值來返回。 * WHERE子句子查詢 依子查詢的結果為單值或多值,使用不同的運算符號 ![](https://i.imgur.com/S3bvWLc.png) > **單值子查詢** :子查詢的返回結果**只有一個數值**。 **多值子查詢** :子查詢的返回結果是 (同一個欄位) **多個數值**。 * WHERE 子句=子查詢 >找出選修「資料庫系統」的學生學號及姓名。 >> 單值子查詢 ```SQL= SELECT A.學號, A.姓名 FROM 學生資料表 AS A , 選課資料表 AS B,課程資料表 AS C WHERE A.學號=B.學號 AND B.課號= ( SELECT C.課號 WHERE 課名='資料庫系統' ); ``` * WHERE 子句>子查詢 > 找出操行成績大於平均操行成績的學生。 >> 單值子查詢 ```SQL= SELECT A.學號 , A.姓名 ,B.操行成績 FROM 學生資料表 AS A, 學務處資料表 AS B WHERE A.學號 = B.學號 AND B.操行成績> (SELECT AVG(操行成績) FROM 學務處資料表) ``` * Where子句 - 主查詢交叉比對子查詢 >找出選修「課號為C005」的學生學號及姓名 >> 單值子查詢 ```SQL= SELECT A.學號, A.姓名 FROM 學生資料表 AS A WHERE A.學號 = (SELECT 學號 FROM 選課資料表 AS B WHERE A.學號 = B.學號 AND B.課號='C005'); ``` * Where子句IN子查詢 > 找出有修「資料」開頭的課程之同學 >> 多值子查詢 ```SQL= SELECT Distinct A.學號, A.姓名 FROM 學生資料表 AS A, 選課資料表 AS B WHERE A.學號 = B.學號 AND B.課號 IN (SELECT C.課號 FROM 課程資料表 AS C WHERE 課名 LIKE '資料%'); ``` * Where子句ALL子查詢 > 找出「甲班成績單」中有那些同學的「成績」比「乙班成績 單」中所有同學的「成績」高 >> 有些MySQL版本不支援 ```SQL= SELECT * FROM 甲班成績單 WHERE 成績 > ALL (SELECT 成績 FROM 乙班成績單) ``` * Where子句ANY子查詢 > 找出「甲班成績單」中有那些同學的「成績」比「乙班成績 單」中任何同學的「成績」低 >> 有些MySQL版本不支援 ```SQL= SELECT * FROM 甲班成績單 WHERE 成績 < Any (SELECT 成績 FROM 乙班成績單) ``` * Where子句EXISTS子查詢 > 找出有修「資料」開頭的課程之同學 >> 布林子查詢 ```SQL= SELECT Distinct A.學號, A.姓名 FROM 學生資料表 AS A, 選課資料表 AS B WHERE A.學號 = B.學號 AND EXISTS (SELECT C.課號 FROM 課程資料表 AS C WHERE 課名 = '資料庫系統'); ``` * From 子句子查詢 > 子查詢出現在From子句中,子查詢結果為一個表格(子表、臨時表)。 ```sql= SELECT A.課號, A.學號, A.成績, B.平均分 FROM 選課資料表 AS A INNER Join (SELECT 課號, AVG(成績) AS 平均分 FROM 選課資料表 GROUP BY 課號) AS B ON (A.課號 = B.課號) ORDER BY A.課號, A.學號 ``` * Select list 子查詢 > 請列出教職員「編號,姓名」及其主管的「主管代碼、主管姓名」 ```sql= SELECT 編號, 姓名, 主管 AS 主管編號, (Select 姓名 from 教職員資料表 AS B where A.主管=B.編號) AS 主管姓名 FROM 教職員資料表 AS A; ```