有時你可能想將查詢結果作為另一個查詢的欄位,或作為查詢欄位的標準。 舉例來說,假設你想看到每個產品的訂單間隔。 要建立一個查詢來顯示這個區間,你需要將每個訂單日期與該產品的其他訂單日期做比較。 比較這些訂單日期也需要查詢。 你可以透過使用子查詢,將此查詢巢狀嵌入主查詢中。
你可以在表達式中寫子查詢,或在 SQL 視圖中寫 結構化查詢語言 (SQL) (SQL) 陳述句。
本文內容
將查詢結果作為另一個查詢的欄位使用
你可以用子查詢作為欄位別名。 當你想在主查詢中將子查詢結果當作欄位時,使用子查詢作為欄位別名。
注意
你用作欄位別名的子查詢不能回傳超過一個欄位。
你可以用子查詢欄位別名來顯示依賴當前列其他值的值,這在沒有子查詢的情況下是無法做到的。
舉例來說,讓我們回到你想看到每個產品訂單間隔的例子。 要確定這個區間,你需要將每個訂單日期與該產品的其他訂單日期做比較。 你可以使用 Northwind 資料庫範本建立查詢來顯示這些資訊。
按一下 [檔案] 索引標籤上的 [新增]。
在 「可用範本」中,點選 「範例範本」。
點選 Northwind,然後點 「建立」。
依照 [北風貿易] 頁面上的指示 (在 [啟動畫面] 物件索引籤上) 開啟資料庫,然後關閉 [登入對話方塊] 視窗。
在 [建立] 索引標籤的 [查詢] 群組中,按一下 [查詢設計]。
點選「 查詢 」標籤,然後雙擊「 產品訂單」。
雙擊產品 識別 碼欄位和 訂單日期 欄位,即可將它們加入查詢設計網格。
在格子產品識別欄的排序列中,選擇「升天」。
在網格的排序日期欄的排序列中,選擇「下降」。
在格子的第三欄,右鍵點擊 欄位 列,然後在快捷鍵選單中點 選「放大 」。
在 Zoom 對話框中,輸入或貼上以下表達式:
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]
此表達式計算每個訂單日期與該產品先前訂單日期之間的區間,並利用我們透過子查詢定義的先前訂單日期值。在 [設計] 索引標籤上的 [結果] 群組中,按一下 [執行]。
- 查詢會執行並顯示產品名稱、訂單日期、先前訂單日期及訂單日期之間的間隔清單。 結果先依產品 ID () 升序排序,再依訂單日期 () 排序。
-
注意
由於產品 ID 是查詢欄位,預設情況下,Access 會顯示查詢值 (此處是產品名稱) ,而非實際的產品 ID。 雖然這會改變顯示的值,但排序順序不會改變。
關閉 Northwind 資料庫。
使用子查詢作為查詢欄位的標準
你可以用子查詢作為欄位準則。 當你想用子查詢的結果來限制該欄位顯示的值時,可以用子查詢作為欄位的準則。
舉例來說,假設你想檢視一份由 非 銷售代表員工處理的訂單清單。 要產生這個清單,你需要將每筆訂單的員工編號與非銷售代表員工的員工編號清單進行比較。 要建立這個清單並將其作為欄位準則,你使用一個子查詢,如以下程序所示:
打開 Northwind.accdb 並啟用其內容。
關閉登入表單。
在 [建立] 索引標籤的 [其他] 群組中,按一下 [查詢設計]。
在 「表格」 標籤中,雙擊「 訂單 與 員工」。
在訂單表中,雙擊員工 識別 欄位、 訂單識別 碼欄位和 訂單日期 欄位,即可將它們加入查詢設計網格。 在員工表格中,雙擊職 稱 欄位即可將其加入設計網格。
右鍵點選員工ID欄的 條件 列,然後在捷徑選單中點選 「縮放 」。
在 Zoom 框中,輸入或貼上以下表達式:
IN (SELECT [ID] FROM [Employees] WHERE [Job Title]<>'Sales Representative')這就是子查詢。 它會選擇所有員工沒有銷售代表職稱的員工 ID,並將該結果集提供給主要查詢。 主要查詢接著檢查訂單資料表中的員工 ID 是否包含在結果集中。
在 [設計] 索引標籤上的 [結果] 群組中,按一下 [執行]。
查詢執行後,查詢結果顯示一份由非銷售代表員工處理的訂單清單。
你可以搭配子查詢使用的常用 SQL 關鍵字
你可以用幾個SQL關鍵字來搭配子查詢:
注意
此清單並非完整。 你可以在子查詢中使用任何有效的 SQL 關鍵字,但不含資料定義關鍵字。
全部 在 WHERE 子句中使用 ALL,取得符合條件的列,與子查詢回傳的每一列相比。
舉例來說,假設你正在分析一所大學的學生數據。 學生必須維持最低GPA,該標準因主修而異。 主修及其最低GPA會儲存在名為「主修」的表格中,相關學生資訊則儲存在名為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,該標準因主修而異。 主修及其最低GPA會儲存在名為「主修」的表格中,相關學生資訊則儲存在名為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 同義。
現存 在 WHERE 子句中使用 EXIST,表示子查詢至少應回傳一列。 你也可以在 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]);在 在 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');