MYSQL中使用子查詢進行過濾

子查詢

查詢(query) 任何SQL語句都是查詢。但此術語一般指SELECT語句。

SQL還允許創建子查詢(subquery),即嵌套在其他查詢中的查詢

利用子查詢進行過濾

例子:假如需要列出訂購物品RGAN01的所有客戶
(1) 檢索包含物品RGAN01的所有訂單的編號。
(2) 檢索具有前一步驟列出的訂單編號的所有客戶的ID。
(3) 檢索前一步驟返回的所有客戶ID的客戶信息。

輸入

SELECT order_num 
FROM OrderItems 
WHERE prod_id = 'RGAN01';

輸出

+-----------+
| order_num |
+-----------+
|     20007 |
|     20008 |
+-----------+

輸入

SELECT cust_id 
FROM Orders 
WHERE order_num IN (20007,20008); 

輸出

+------------+
| cust_id    |
+------------+
| 1000000004 |
| 1000000005 |
+------------+

輸入

SELECT cust_id
FROM orders
WHERE order_num IN (SELECT order_num
                    FROM orderitems
                    WHERE prod_id = 'RGAN01');

輸出

+------------+
| cust_id    |
+------------+
| 1000000004 |
| 1000000005 |
+------------+

分析:在SELECT語句中,子查詢總是從內向外處理。在處理上面的SELECT語句時,MySQL實際上執行了兩個操作
首先是:
SELECT order_num FROM orderitems WHERE prod_id = ‘RGAN01’
次查詢返回連個訂單號:20007和20008。然後這兩個值以IN操作符要求的逗號分隔的格式傳遞給外部查詢的WHERE子句。

外部查詢完成:
SELECT cust_id FROM orders WHERE order_num IN(20007,20008)
可以看到,輸出是正確的並與前面硬編碼WHERE子句所返回的值相同。

現在得到了訂購物品RGAN01的所有客戶的ID。下一步是檢索這些客戶ID的客戶信息。

輸入

SELECT cust_name,cust_contact
FROM customers
WHERE cust_id IN ('1000000004','1000000005');

可以把其中的WHERE子句轉換爲子查詢而不是硬編碼這些客戶ID:

輸入

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 = 'RGAN01'));

輸出

+---------------+--------------------+
| cust_name     | cust_contact       |
+---------------+--------------------+
| Fun4All       | Denise L. Stephens |
| The Toy Store | Kim Howard         |
+---------------+--------------------+

分析:
爲了執行上述SELECT語句,MySQL實際上必須執行3條SELECT語句。最裏邊的子查詢返回訂單號列表,此列表用於其外面的子查詢的WHERE子句。外面的子查詢返回客戶ID列表,此客戶ID列表用於最外層查詢的WHERE子句。最外層查詢確實返回所需的數據。

作爲計算字段使用子查詢

使用子查詢的另一方法是創建計算字段。假如需要顯示customers表中每個客戶的訂單總數。訂單與相應的客戶ID存儲在orders表中。

爲了執行這個操作,遵循下面的步驟。
(1) 從customers表中檢索客戶列表。
(2) 對於檢索出的每個客戶,統計其在orders表中的訂單數目。

使用SELECT COUNT(*)對錶中的行進行計數,並且通過提供一條WHERE子句來過濾某個特定的客戶ID,可僅對該客戶的訂單進行計數。
爲了對每個客戶執行COUNT(*)計算,應該將COUNT(*)作爲一個子查詢

輸入

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 |
+---------------+------------+--------+
| Fun4All       | IN         |      1 |
| Fun4All       | AZ         |      1 |
| Kids Place    | OH         |      0 |
| The Toy Store | IL         |      1 |
| Village Toys  | MI         |      2 |
+---------------+------------+--------+

分析:這條SELECT語句對customers表中每個客戶返回3列:cust_name、cust_state和orders。orders是一個計算字段,它是由圓括號中的子查詢建立的。該子查詢對檢索出的每個客戶執行一次。在此例子中,該子查詢執行了5次,因爲檢索出了5個客戶。

子查詢中的WHERE子句與前面使用的WHERE子句稍有不同,因爲它使
用了完全限定列名(在第4章中首次提到)。下面的語句告訴SQL比較
orders表中的cust_id與當前正從customers表中檢索的cust_id:

WHERE orders.cust_id = customers.cust_id

相關子查詢(correlated subquery) 涉及外部查詢的子查詢
這種類型的子查詢稱爲相關子查詢。
任何時候只要列名可能有多義性,就必須使用這種語法(表名和列名由一個句點分隔)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章