14.1 利用子查詢進行過濾
現在,假如需要列出訂購物品TNT2的所有客戶,應該怎樣檢索?下面列出具體的步驟。
- 檢索包含物品TNT2的所有訂單的編號。
- 檢索具有前一步驟列出的訂單編號的所有客戶的ID。
- 檢索前一步驟返回的所有客戶ID的客戶信息。
上述每個步驟都可以單獨作爲一個查詢來執行。可以把一條SELECT語句返回的結果用於另一條SELECT語句的WHERE子句。
mysql> SELECT cust_name, cust_contact FROM customers WHERE cust_id IN (
-> SELECT cust_id FROM orders WHERE order_num IN (
-> SELECT order_num FROM orderitems WHERE prod_id='TNT2'));
+----------------+--------------+
| cust_name | cust_contact |
+----------------+--------------+
| Coyote Inc. | Y Lee |
| Yosemite Place | Y Sam |
+----------------+--------------+
- 分析:最裏邊的子查詢返回訂單號列表,此列表用於其外面的子查詢的WHERE子句。外面的子查詢返回客戶ID列表,此客戶ID列表用於最外層查詢的WHERE子句。最外層查詢確實返回所需的數據。
對於能嵌套的子查詢的數目沒有限制,不過在實際使用時由於性能的限制,不能嵌套太多的子查詢。雖然子查詢一般與IN操作符結合使用,但也可以於測試等於(=)、不等於(<>)等。
列必須匹配:在WHERE子句中使用子查詢(如這裏所示),應該保證SELECT語句具有與WHERE子句中相同數目的列。
14.2 作爲計算字段使用子查詢
mysql> SELECT cust_name, cust_state,(
-> SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;
+----------------+------------+--------+
| cust_name | cust_state | orders |
+----------------+------------+--------+
| Coyote Inc. | MI | 2 |
| E Fudd | IL | 1 |
| Mouse House | OH | 0 |
| Wascals | IN | 1 |
| Yosemite Place | AZ | 1 |
+----------------+------------+--------+
- 分析:這 條 SELECT 語 句 對
customers
表 中 每 個 客 戶 返 回 3 列 :cust_name
、cust_state
和orders
。orders
是一個計算字段,它是由圓括號中的子查詢建立的。該子查詢對檢索出的每個客戶執行一次。在此例子中,該子查詢執行了5次,因爲檢索出了5個客戶。
子查詢中的WHERE
子句與前面使用的WHERE
子句稍有不同,因爲它使用了完全限定列名。下面的語句告訴SQL比較orders
表中的cust_id
與當前正從customers
表中檢索的cust_id
:
WHERE orders.cust_id = customers.cust_id
相關子查詢(correlated subquery) 涉及外部查詢的子查詢。
這種類型的子查詢稱爲相關子查詢。任何時候只要列名可能有多義性,就必須使用這種語法(表名和列名由一個句點分隔)。