SQL 中的嵌套查詢
SQL 語言允許您將一個查詢嵌套在另一個查詢中。這使得編寫一個非常大的查詢成為可能,該查詢將執行大型和復雜的操作,儘管代碼的可讀性大大降低。
根據子查詢返回的值的多少,它們可以應用的區域會發生變化。一共有三個選項:
- 子查詢返回一個單一值(一列和一行)。
- 子查詢返回一個值列表(一個只有一列的表)。
- 子查詢返回一個表(許多列,任意數量的行)。
讓我們看一下每種情況的一個例子。
帶有標量結果的子查詢
讓我們從員工表中找出薪水高於公司平均水平的所有員工的列表。我們該怎麼做?
如果我們事先知道,我們可以通過將他們的工資與平均工資進行比較來輕鬆過濾員工。同時,我們已經編寫了一個查詢,可以讓我們計算公司員工的平均工資。讓我們記住它:
SELECT AVG(salary) FROM employee
然後 MySQL 返回值:76833.3333。
現在如何找到工資高於平均水平的所有員工的列表?這也很簡單:
SELECT * FROM employee
WHERE salary > 76833.3333
此查詢的結果將是:
ID | 姓名 | 職業 | 薪水 |
---|---|---|---|
1個 | 伊万諾夫伊万 | 程序員 | 100000 |
2個 | 彼得羅夫彼得 | 程序員 | 80000 |
4個 | 拉比諾維奇·莫伊沙 | 導演 | 200000 |
現在我們只需用第一個請求代替值 76833 來合併兩個請求:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
此查詢的結果將是相同的:
ID | 姓名 | 職業 | 薪水 |
---|---|---|---|
1個 | 伊万諾夫伊万 | 程序員 | 100000 |
2個 | 彼得羅夫彼得 | 程序員 | 80000 |
4個 | 拉比諾維奇·莫伊沙 | 導演 | 200000 |
帶有值列表的子查詢
你還記得我們曾經有過一個任務——從一個表中找到所有在另一個表中沒有對應記錄的記錄嗎?
還有這張圖:
如果我沒記錯的話,任務如下:顯示員工表中沒有任務的所有員工的列表。
讓我們也分兩步找到解決方案。
首先,讓我們編寫一個查詢,返回在任務表中有任務的所有員工的 ID。只要記住兩件事:
- 刪除重複項 - 使用 DISTINCT 關鍵字。
- 從結果中移除 NULL 值。
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
在這裡,我們得到了這樣一個請求的漂亮結果:
員工ID |
---|
1個 |
2個 |
5個 |
4個 |
6個 |
為了方便,我們暫時記為一個序列:1,2,5,4,6。現在讓我們編寫第二個查詢 - 到 employee 表,它將返回其 id 不包含在第一個列表中的員工列表:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
這個查詢的結果是:
ID | 姓名 | 職業 | 薪水 | 年齡 | 加入日期 |
---|---|---|---|---|---|
3個 | 伊万諾夫謝爾蓋 | 測試儀 | 40000 | 三十 | 2014-01-01 |
現在,與前面的示例一樣,您可以通過簡單地替換第一個請求的主體而不是 id 列表來合併兩個請求。
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)
GO TO FULL VERSION