目錄匯總:SQL 零基礎入門教程
SELECT 語句 是 SQL 的查詢。我們迄今為止所看到的所有 SELECT
語句都是簡單查詢,即從單個數據庫表中檢索數據的單條語句。
查詢(query)
任何 SQL 語句都是查詢。但此術語一般指 SELECT 語句。
SQL 還允許創建子查詢(subquery),即嵌套在其他查詢中的查詢。為什么要這樣做呢?理解這個概念的最好方法是考察幾個例子。
一、利用子查詢進行過濾
本教程所有部分中使用的數據庫表都是關系表(關於每個表及關系的描述,請參閱 樣例表腳本)。訂單存儲在兩個表中。每個訂單包含訂單編號、客戶 ID、訂單日期,在 Orders
表中存儲為一行。各訂單的物品存儲在相關的 OrderItems
表中。Orders
表不存儲顧客信息,只存儲顧客 ID。顧客的實際信息存儲在 Customers
表中。
現在,假如需要列出訂購物品 RGAN01 的所有顧客,應該怎樣檢索?下面列出具體的步驟。
(1) 檢索包含物品 RGAN01 的所有訂單的編號。
(2) 檢索具有前一步驟列出的訂單編號的所有顧客的 ID。
(3) 檢索前一步驟返回的所有顧客 ID 的顧客信息。
上述每個步驟都可以單獨作為一個查詢來執行。可以把一條 SELECT
語句返回的結果用於另一條 SELECT
語句的 WHERE
子句。
也可以使用子查詢來把 3 個查詢組合成一條語句。
第一條 SELECT
語句的含義很明確,它對 prod_id
為 RGAN01 的所有訂單物品,檢索其 order_num
列。輸出列出了兩個包含此物品的訂單:
輸入▼
SELECT order_num
FROM OrderItems
WHERE prod_id = 'RGAN01';
輸出▼
order_num
-----------
20007
20008
現在,我們知道了哪個訂單包含要檢索的物品,下一步查詢與訂單 20007 和 20008 相關的顧客 ID。利用 IN 操作符 介紹的 IN
子句,編寫如下的 SELECT
語句:
輸入▼
SELECT cust_id
FROM Orders
WHERE order_num IN (20007,20008);
輸出▼
cust_id
----------
1000000004
1000000005
現在,結合這兩個查詢,把第一個查詢(返回訂單號的那一個)變為子查詢。請看下面的 SELECT
語句:
輸入▼
SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
FROM OrderItems
WHERE prod_id = 'RGAN01');
輸出▼
cust_id
----------
1000000004
1000000005
分析▼
在 SELECT
語句中,子查詢總是從內向外處理。在處理上面的 SELECT
語句時,DBMS 實際上執行了兩個操作。
首先,它執行下面的查詢:
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
子句所返回的值相同。
提示:格式化 SQL
包含子查詢的
SELECT
語句難以閱讀和調試,它們在較為復雜時更是如此。如上所示,把子查詢分解為多行並進行適當的縮進,能極大地簡化子查詢的使用。順便一提,這就是顏色編碼起作用的地方,好的 DBMS 客戶端正是出於這個原因使用了顏色代碼 SQL。
現在得到了訂購物品 RGAN01 的所有顧客的ID。下一步是檢索這些顧客 ID 的顧客信息。檢索兩列的 SQL 語句為:
輸入▼
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
語句,DBMS 實際上必須執行三條 SELECT
語句。最里邊的子查詢返回訂單號列表,此列表用於其外面的子查詢的 WHERE
子句。外面的子查詢返回顧客 ID 列表,此顧客 ID 列表用於最外層查詢的 WHERE
子句。最外層查詢返回所需的數據。
可見,在 WHERE
子句中使用子查詢能夠編寫出功能很強且很靈活的 SQL 語句。對於能嵌套的子查詢的數目沒有限制,不過在實際使用時由於性能的限制,不能嵌套太多的子查詢。
注意:只能是單列
作為子查詢的
SELECT
語句只能查詢單個列。企圖檢索多個列將返回錯誤。
注意:子查詢和性能
這里給出的代碼有效,並且獲得了所需的結果。但是,使用子查詢並不總是執行這類數據檢索的最有效方法。
請參閱
(完)