SQL巢狀查詢
結構化查詢語言 (SQL) 是一種程式語言。SQL 用於管理儲存在關係資料庫中的資料。SQL 具有巢狀查詢的能力。巢狀查詢是在另一個查詢內的查詢。巢狀查詢允許更復雜和更具體的資料檢索。在本文中,我們將討論 SQL 中的巢狀查詢、它們的語法和示例。
巢狀查詢
在 SQL 中,巢狀查詢是指將一個查詢放在另一個查詢中的查詢。內部查詢的輸出由外部查詢使用。巢狀查詢有兩個 SELECT 語句:一個用於內部查詢,另一個用於外部查詢。

巢狀查詢的語法
巢狀查詢的基本語法包括將一個查詢放在另一個查詢內。內部查詢或子查詢首先執行,並返回一組隨後由外部查詢使用的值。巢狀查詢的語法如下:
SELECT column1, column2, ... FROM table1 WHERE column1 IN ( SELECT column1 FROM table2 WHERE condition );
SQL 中巢狀查詢的型別
子查詢可以是關聯的或非關聯的。

非關聯(或獨立)巢狀查詢
非關聯(或獨立)巢狀查詢:非關聯(或獨立)子查詢獨立於外部查詢執行。它們的結果將傳遞給外部查詢。
關聯巢狀查詢
關聯子查詢為外部查詢的每一行執行一次。它們使用外部查詢中的值來返回結果。
獨立巢狀查詢的執行順序
在獨立巢狀查詢中,執行順序是從最內層查詢到最外層查詢。在內部查詢完成執行之前,不會執行外部查詢。外部查詢使用內部查詢的結果。
獨立巢狀查詢中使用的運算子
IN 運算子
此運算子檢查外部查詢結果中的列值是否出現在內部查詢的結果中。最終結果將包含滿足 IN 條件的行。
NOT IN 運算子
此運算子檢查外部查詢結果中的列值是否未出現在內部查詢的結果中。最終結果將包含滿足 NOT IN 條件的行。
ALL 運算子
此運算子將外部查詢結果的值與內部查詢結果的所有值進行比較,如果匹配所有值,則返回該行。
ANY 運算子
此運算子將外部查詢結果的值與所有內部查詢結果值進行比較,如果與任何值匹配,則返回該行。
關聯巢狀查詢的執行順序
在關聯巢狀查詢中,內部查詢使用來自外部查詢的值,並且執行順序與獨立巢狀查詢不同。
首先,外部查詢選擇第一行。
內部查詢使用所選行的值。它執行其查詢並返回結果集。
外部查詢使用內部查詢返回的結果集。它確定是否應將所選行包含在最終輸出中。
步驟 2 和 3 對外部查詢結果集中的每一行重複。
此過程可能需要大量資源。如果查詢未正確最佳化,則可能導致效能問題。
關聯巢狀查詢中使用的運算子
在關聯巢狀查詢中,可以使用以下運算子:
EXISTS 運算子
此運算子檢查子查詢是否返回任何行。如果返回至少一行,EXISTS 運算子返回 true,並且外部查詢繼續執行。如果子查詢不返回任何行,則 EXISTS 運算子返回 false,並且外部查詢停止執行。
NOT EXISTS 運算子
此運算子檢查子查詢是否不返回任何行。如果子查詢不返回任何行,則 NOT EXISTS 運算子返回 true,並且外部查詢繼續執行。如果子查詢返回至少一行,則 NOT EXISTS 運算子返回 false,並且外部查詢停止執行。
ANY 運算子
此運算子將外部查詢結果的值與內部查詢返回的一個或多個值進行比較。如果與內部查詢返回的任何一個值進行比較為真,則該行將包含在最終結果中。
ALL 運算子
此運算子將外部查詢結果的值與內部查詢返回的所有值進行比較。只有當與內部查詢返回的所有值進行比較為真時,該行才會包含在最終結果中。
這些運算子用於建立依賴於外部查詢的值才能執行的關聯巢狀查詢。
示例
考慮以下示例表,以便對這些表執行巢狀查詢。
表:employees 表
emp_id |
emp_name |
dept_id |
---|---|---|
1 |
John |
1 |
2 |
Mary |
2 |
3 |
Bob |
1 |
4 |
Alice |
3 |
5 |
Tom |
1 |
表:departments 表
dept_id |
dept_name |
---|---|
1 |
銷售部 |
2 |
市場部 |
3 |
財務部 |
表:sales 表
sale_id |
emp_id |
sale_amt |
---|---|---|
1 |
1 |
1000 |
2 |
2 |
2000 |
3 |
3 |
3000 |
4 |
1 |
4000 |
5 |
5 |
5000 |
6 |
3 |
6000 |
7 |
2 |
7000 |
示例 1:查詢銷售部門中所有員工的姓名。
所需查詢
SELECT emp_name FROM employees WHERE dept_id IN (SELECT dept_id FROM departments WHERE dept_name = 'Sales');
輸出
emp_name |
---|
John |
Bob |
Tom |
示例 2:查詢所有進行過銷售的員工的姓名
所需查詢
SELECT emp_name FROM employees WHERE EXISTS (SELECT emp_id FROM sales WHERE employees.emp_id = sales.emp_id);
輸出
emp_name |
---|
John |
Mary |
Bob |
Alice |
Tom |
此查詢從“employees”表中選擇所有員工,條件是在“sales”表中存在該員工的銷售記錄。
示例 3:查詢所有銷售額大於$1000 的員工的姓名。
所需查詢
SELECT emp_name FROM employees WHERE emp_id = ALL (SELECT emp_id FROM sales WHERE sale_amt > 1000);
輸出
emp_name |
---|
John |
Mary |
Bob |
Alice |
Tom |
此查詢從“employees”表中選擇所有員工。條件是他們的 emp_id 等於“sales”表中銷售額大於$1000 的所有 emp_id。由於所有員工的銷售額都大於$1000,因此返回所有員工姓名。