有時候您可能會想要將查詢的結果當做另一個查詢中的欄位,或做為查詢欄位的準則。 例如,假設您想要查看每個產品的訂單間隔。 若要建立顯示此區間的查詢,您必須比較每個訂單日期與該產品的其他訂單日期。 比較這些訂單日期也需要查詢。 您可以使用 子查詢,將此查詢巢狀嵌入主要查詢內。
您可以在 SQL 檢視的 運算式 或 結構化查詢語言 (SQL) (SQL) 語句中撰寫子查詢。
本文內容
使用查詢的結果做為另一個查詢中的欄位
您可以使用子查詢做為欄位別名。 當您想要使用子查詢結果做為主查詢中的欄位時,請使用子查詢做為字段別名。
附註: 您做為欄位別名的子查詢無法傳回多個字段。
您可以使用子查詢欄位別名來顯示相依於目前列中其他值的值,而不需要使用子查詢就無法使用。
例如,讓我們回到您想要查看每個產品每筆訂單之間的間隔的範例。 若要判斷此間隔,您需要比較每個訂單日期與該產品的其他訂購日期。 您可以使用 [北風] 資料庫範本建立顯示此資訊的查詢。
-
按一下 [檔案] 索引標籤上的 [新增]。
-
在 [可用的範本] 底下,按兩下 [ 範例]。
-
按兩下 [北風],然後按兩下 [ 建立]。
-
依照 [北風貿易] 頁面上的指示 (在 [啟動畫面] 物件索引籤上) 開啟資料庫,然後關閉 [登入對話方塊] 視窗。
-
在 [建立] 索引標籤的 [查詢] 群組中,按一下 [查詢設計]。
-
按兩下 [ 查詢] 索 引標籤,然後按兩下 [ 產品訂單]。
-
按兩下 [產品識別碼 ] 字段和 [ 訂單日期] 字 段,將它們新增至查詢設計網格線。
-
在網格線 [產品標識符] 欄的 [排序] 列中,選取 [遞增]。
-
在網格線 [順序日期] 欄的 [排序] 列中,選取 [遞減]。
-
在網格線的第三欄中,以滑鼠右鍵按兩下 [ 功能變數 ] 列,然後按兩下快捷方式選單上的 [ 縮 放]。
-
在 [ 縮放] 對話框中,輸入或貼上下列表示式:
Prior Date: (SELECT MAX([Order Date])
FROM [Product Orders] AS [Old Orders]
WHERE [Old Orders].[Order Date] < [Product Orders].[Order Date]
AND [Old Orders].[Product ID] = [Product Orders].[Product ID])此表達式為子查詢。 針對每一列,子查詢會選取比與該數據列相關聯的訂單日期還要短的最新訂單日期。 請注意,您如何使用 AS 關鍵詞來建立數據表別名,以便將子查詢中的值與主要查詢目前列中的值進行比較。
-
在網格線的第四欄的 [ 字段 ] 列中,輸入下列表達式:
Interval: [Order Date]-[Prior Date]
此表達式會使用我們使用子查詢所定義之前一個日期的值,計算每個訂單日期與該產品前次訂單日期之間的間隔。
-
在 [設計] 索引標籤上的 [結果] 群組中,按一下 [執行]。
-
查詢會執行並顯示產品名稱、訂單日期、前次訂單日期,以及訂單日期之間的間隔清單。 結果會先依 [產品標識符] () 的遞增順序排序,再依 [訂單日期] (以遞減順序) 排序。
-
附註: 由於產品標識碼是查閱欄位,因此根據預設,Access 會在此情況下顯示查閱值 (,產品名稱會) ,而不是實際的產品標識碼。 雖然這會變更顯示的值,但不會變更排序順序。
-
-
關閉 [北風] 資料庫。
使用子查詢做為查詢欄位的準則
您可以使用子查詢做為欄位準則。 當您想要使用子查詢的結果來限制字段顯示的值時,請使用子查詢做為字段準則。
例如,假設您想要檢閱 非 銷售代表的員工所處理的訂單清單。 若要產生這份清單,您必須比較每筆訂單的員工標識碼,以及非銷售代表員工的員工標識符清單。 若要建立此列表並將其做為字段準則,請使用子查詢,如下列程式所示:
-
開啟 Northwind.accdb 並啟用其內容。
-
關閉登入表單。
-
在 [建立] 索引標籤的 [其他] 群組中,按一下 [查詢設計]。
-
在 [ 數據表] 索引 標籤上,按兩下 [ 訂單 與 員工]。
-
在 [訂單] 數據表中,按兩下 [員工標識符 ] 字段、[ 訂單標識符 ] 欄位和 [ 訂單日期] 字 段,將其新增至查詢設計網格線。 在 [員工] 數據表中,按兩下 [ 職稱] 字 段,將其新增至設計網格線。
-
以滑鼠右鍵按兩下 [員工標識符] 欄的 [ 準則 ] 列,然後按下快捷方式功能表上的 [ 縮 放]。
-
在 [ 縮放] 方 塊中,輸入或貼上下列表示式:
IN (SELECT [ID] FROM [Employees]
WHERE [Job Title]<>'Sales Representative')這是子查詢。 它會選取員工沒有銷售代表職稱的所有員工標識符,並提供設定為主要查詢的結果。 主查詢接著會檢查 [訂單] 數據表中的員工標識碼是否在結果集中。
-
在 [設計] 索引標籤上的 [結果] 群組中,按一下 [執行]。
查詢會執行,查詢結果會顯示非銷售代表的員工所處理的訂單清單。
您可以搭配子查詢使用的常見 SQL 關鍵詞
有幾個 SQL 關鍵詞可以搭配子查詢使用:
附註: 這份清單並不詳盡。 您可以在子查詢中使用任何有效的 SQL 關鍵詞,但數據定義關鍵詞除外。
-
所有 在 WHERE 子句中使用 ALL 來擷取符合條件的列,相較於子查詢傳回的每一列時。
例如,假設您正在分析某校的學生數據。 學生必須維護從主要到主修科目的至少 GPA。 主修科目及其最小 GDA 會儲存在名為 [主修科目] 的數據表中,而相關的學生資訊會儲存在名為 [Student_Records] 的數據表中。
若要查看主修 (及其最小 GPA) 清單,其中每位具有該主修科目的學生都超過最小 GPA,您可以使用下列查詢:
SELECT [Major], [Min_GPA]
FROM [Majors]
WHERE [Min_GPA] < ALL
(SELECT [GPA] FROM [Student_Records]
WHERE [Student_Records].[Major]=[Majors].[Major]); -
任何 在 WHERE 子句中使用 ANY 來擷取符合條件的列,比對子查詢傳回的至少其中一列。
例如,假設您正在分析某校的學生數據。 學生必須維護從主要到主修科目的至少 GPA。 主修科目及其最小 GDA 會儲存在名為 [主修科目] 的數據表中,而相關的學生資訊會儲存在名為 [Student_Records] 的數據表中。
若要查看主修科目 (及其最小 GPA) 列表,讓任何具有該主修的學生不符合最小 GPA,您可以使用下列查詢:
SELECT [Major], [Min_GPA]
FROM [Majors]
WHERE [Min_GPA] > ANY
(SELECT [GPA] FROM [Student_Records]
WHERE [Student_Records].[Major]=[Majors].[Major]);附註: 您也可以將 SOME 關鍵詞用於相同的用途;SOME 關鍵詞是 ANY 的同義字。
-
EXISTS 在 WHERE 子句中使用 EXISTS,表示子查詢至少應傳回一列。 您也可以在 「EXISTS」的前置詞「NOT」,表示子查詢不應傳回任何數據列。
例如,下列查詢會傳回至少以一個現有訂單找到的產品清單:
SELECT *
FROM [Products]
WHERE EXISTS
(SELECT * FROM [Order Details]
WHERE [Order Details].[Product ID]=[Products].[ID]);使用NOT EXISTS,查詢會傳回至少一個現有訂單中找不到的產品清單:
SELECT *
FROM [Products]
WHERE NOT EXISTS
(SELECT * FROM [Order Details]
WHERE [Order Details].[Product ID]=[Products].[ID]); -
IN 在 WHERE 子句中使用 IN,確認主查詢目前列中的值是子查詢傳回集合的一部分。 您也可以在 IN 的前置詞為 NOT,確認主查詢目前數據列中的值不屬於子查詢傳回的集合。
例如,下列查詢會傳回訂單 (清單,) 非銷售代表的員工處理訂單日期:
SELECT [Order ID], [Order Date]
FROM [Orders]
WHERE [Employee ID] IN
(SELECT [ID] FROM [Employees]
WHERE [Job Title]<>'Sales Representative');您可以使用 NOT IN,以這種方式撰寫相同的查詢:
SELECT [Order ID], [Order Date]
FROM [Orders]
WHERE [Employee ID] NOT IN
(SELECT [ID] FROM [Employees]
WHERE [Job Title]='Sales Representative');