外部連接的原因
順便說一句,你還記得我們合併電子表格時辦公室清潔任務因為沒有清潔工而消失了嗎?
如果您運行這樣的查詢:
SELECT * FROM task
然後我們得到這個結果:
ID | emploee_id | 姓名 | 最後期限 |
---|---|---|---|
1個 | 1個 | 修復一個前端bug | 2022-06-01 |
2個 | 2個 | 修復後端的一個bug | 2022-06-15 |
3個 | 5個 | 買咖啡 | 2022-07-01 |
4個 | 5個 | 買咖啡 | 2022-08-01 |
5個 | 5個 | 會買咖啡 | 2022-09-01 |
6個 | (無效的) | 打掃辦公室 | (無效的) |
7 | 4個 | 享受生活 | (無效的) |
8個 | 6個 | 享受生活 | (無效的) |
如果我們嘗試通過 employee_id 連接任務表和員工表,“Clear Office”任務就會消失。
為解決此問題,已將各種修飾符添加到 JOIN 運算符中,以允許此類孤立行在不成對的情況下存儲在另一個表中。
讓我提醒您 JOIN 運算符的經典形式:
table 1 JOIN table 2 ON
condition
我們可以告訴 SQL Server 確保左表 (table1) 中的所有數據都存在於連接表中。即使在右表中沒有它們的對。為此,您只需要編寫:
table 1 LEFT JOIN table 2 ON condition
如果您希望連接表具有右表中的所有行,那麼您需要編寫:
table 1 RIGHT JOIN table 2 ON
condition
讓我們編寫一個查詢來組合所有任務和員工,這樣沒有執行者的任務就不會丟失。為此,編寫一個查詢:
SELECT * FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
這個查詢的結果是:
ID | 姓名 | 職業 | 薪水 | 年齡 | 加入日期 | ID | emploee_id | 姓名 |
---|---|---|---|---|---|---|---|---|
1個 | 伊万諾夫伊万 | 程序員 | 100000 | 25 | 2012-06-30 | 1個 | 1個 | 修復一個前端bug |
2個 | 彼得羅夫彼得 | 程序員 | 80000 | 23 | 2013-08-12 | 2個 | 2個 | 修復後端的一個bug |
4個 | 拉比諾維奇·莫伊沙 | 導演 | 200000 | 35 | 2015-05-12 | 7 | 4個 | 享受生活 |
5個 | 基連科阿納斯塔西婭 | 辦公室主管 | 40000 | 25 | 2015-10-10 | 3個 | 5個 | 買咖啡 |
5個 | 基連科阿納斯塔西婭 | 辦公室主管 | 40000 | 25 | 2015-10-10 | 4個 | 5個 | 買咖啡 |
5個 | 基連科阿納斯塔西婭 | 辦公室主管 | 40000 | 25 | 2015-10-10 | 5個 | 5個 | 買咖啡 |
6個 | 瓦斯卡 | 貓 | 1000 | 3個 | 2018-11-11 | 8個 | 6個 | 享受生活 |
(無效的) | (無效的) | (無效的) | (無效的) | (無效的) | (無效的) | 6個 | (無效的) | 打掃辦公室 |
我們的表又增加了一行,有趣的是,裡面有很多NULL值。從員工表中獲取的所有數據都顯示為 NULL,因為員工表中沒有執行“清潔辦公室”任務的執行者。
加入類型
共有 4 種類型的 JOIN。它們如下表所示:
簡要條目 | 長條目 | 解釋 | |
---|---|---|---|
1個 | 加入 | 內部聯接 | 僅表 A 和 B 中的記錄 |
2個 | 左連接 | 左外連接 | 表 A 中沒有一對的所有行必須是 |
3個 | 正確加入 | 右外連接 | 表 B 中沒有一對的所有行必須是 |
4個 | 外部連接 | 全外連接 | 表 A 和 B 中的所有鹼基對行必須是 |
為了簡單起見,如果我們將表表示為集合,那麼 JOIN 可以顯示為一張圖片:
集合交集意味著對於一個表,它所引用的另一個表中有一條對應的記錄。
採訪中的問題
有時,新手程序員在面試時會被一個非常簡單的問題轟炸。鑑於我們的表格,它可以表述如下:
“編寫一個查詢,顯示沒有任務的所有員工的列表。” 首先,讓我們嘗試稍微改寫一下這個問題:“編寫一個查詢,顯示employee 表中沒有任務的所有員工的列表 task 表。” 我們需要得到這個集合:有很多方法可以解決這個問題,但我將從最簡單的開始:首先,您可以使用 LEFT JOIN 連接我們的表,然後使用 WHERE 排除所有用 NULL 填充缺失數據的行。
SELECT * FROM employee e LEFT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
這個查詢的結果是:
ID | 姓名 | 職業 | 薪水 | 年齡 | 加入日期 | ID | emploee_id | 姓名 |
---|---|---|---|---|---|---|---|---|
3個 | 伊万諾夫謝爾蓋 | 測試儀 | 40000 | 三十 | 2014-01-01 | (無效的) | (無效的) | (無效的) |
這個解決方案的唯一缺點是這裡表中的行包含 NULL,並且根據條件我們需要顯示員工列表。
為此,要么需要在 SELECT 中列出 employee 表所需的列,要么需要顯示所有列,可以編寫如下構造:
SELECT e.* FROM employee e, task t
完整的請求將如下所示:
SELECT e.*
FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
此查詢的結果:
ID | 姓名 | 職業 | 薪水 | 年齡 | 加入日期 |
---|---|---|---|---|---|
3個 | 伊万諾夫謝爾蓋 | 測試儀 | 40000 | 三十 | 2014-01-01 |
剩下的方法留給你做功課。我不想剝奪您自己找到它們的樂趣。
GO TO FULL VERSION