在關(guān)系型數(shù)據(jù)庫中,表之間通常以某種方式相互關(guān)聯(lián),允許它們的信息在整個數(shù)據(jù)庫中僅寫入一次。然后,當(dāng)你需要分析數(shù)據(jù)時,你需要組合來自這些相關(guān)表的信息。
要在 SQL 中執(zhí)行此操作,您可以使用JOIN
語句。該LEFT JOIN
語句是可用的各種JOIN語句之一。當(dāng)您使用它連接兩個表時,它會保留第一個表(左表)的所有行,即使第二個表上沒有對應(yīng)的匹配項。
您可以JOIN
在SELECT
查詢中使用連接兩個表table_1
和table_2
,如下所示:
SELECT columns
FROM table_1
LEFT OUTER JOIN table_2
ON relation;
SELECT columns
FROM table_1
LEFT JOIN table_2
ON relation;
首先你寫下哪些列將出現(xiàn)在連接表中。你可以通過在列名前加上表名來指定該列屬于哪個表。如果某些列的名稱(如table_1.column_1
和table_2.column_1
)與SELECT <columns>
.
然后你可以將第一個表的名稱寫為FROM table_1
.
之后,你再將第二個表的名稱寫為LEFT OUTER JOIN table_2
or LEFT JOIN table_2
(省略OUTER
關(guān)鍵字)。
最后,你要編寫用于匹配行的關(guān)系,例如ON table_1.column_A = table_2.column_B
. 通常關(guān)系是通過 id 來的,但它可以是任何列。
SQL LEFT JOIN 示例
假設(shè)你有一個書籍?dāng)?shù)據(jù)庫,其中有兩個表,一個是書籍,另一個是作者。為避免重復(fù)每本書的所有作者信息,該信息位于其自己的表中,并且書籍只有該author_name
列。
BOOK_ID | TITLE | AUTHOR_NAME | PUBL_YEAR |
---|---|---|---|
1 | Uno, nessuno e centomila | 路易吉·皮蘭德羅 | 1926 |
2 | Il visconte dimezzato | 伊塔洛·卡爾維諾 | 1952 |
3 | Le tigri di Mompracem | 埃米利奧·薩爾加里 | 1900 |
4 | Il giorno della civetta | 萊昂納多·夏夏 | 1961 |
5 | A ciascuno il suo | 萊昂納多·夏夏 | 1966 |
6 | Il fu Mattia Pascial | 路易吉·皮蘭德羅 | 1904 |
7 | I Malavoglia | 喬瓦尼·維爾加 | 1881 |
AUTHOR_ID | NAME | YEAR_OF_BIRTH | PLACE_OF_BIRTH | TRVIA |
---|---|---|---|---|
1 | 路易吉·皮蘭德羅 | 1867 | 阿格里真托 | 1934年諾貝爾文學(xué)獎 |
2 | 喬瓦尼·維爾加 | 1840 | 維齊尼 | 1920年至1922年任意大利王國參議員 |
3 | 伊塔洛·斯韋沃 | 1861 | 的里雅斯特 | 真名是Aron Hector Schmitz |
4 | 切薩雷·帕韋塞 | 1908 | 圣斯特凡諾貝爾博 | null |
5 | 朱塞佩·托馬西·迪·蘭佩杜薩 | 1896 | 巴勒莫 | 1934年至1957年任蘭佩杜薩王子 |
我們可以根據(jù)作者的姓名連接這兩個表。使用該books
表作為左表,你可以編寫以下代碼將它們連接起來:
SELECT books.title AS book_title, books.publ_year, books.author_name, authors.year_of_birth, authors.place_of_birth
FROM books
LEFT JOIN authors
ON books.author_name = authors.name
;
讓我們分解一下。
在第一行中,你可以選擇要在最終表格中顯示的列。它也是決定某些列在結(jié)果表中是否具有不同名稱的地方,使用AS
like with books.title AS book_title
。
第二行 ,FROM books
表示要考慮的第一個表,也稱為左表。
然后第三行,LEFT JOIN authors
,說明要考慮的其他表。
ON books.author_name = authors.name
說使用行books.author_name
和匹配表authors.name
。
在此查詢之后,您將獲得如下表,其中未從作者表中獲取信息的行僅顯示NULL
.
BOOK_NAME | PUBL_YEAR | AUTHOR_NAME | YEAR_OF_BIRTH | PLACE_OF_YEAR |
---|---|---|---|---|
Uno, nessuno e centomila | 1926 | 路易吉·皮蘭德羅 | 1867 | 阿格里真托 |
Il visconte dimezzato | 1952 | 伊塔洛·卡爾維諾 | null | null |
Le tigri di Mompracem | 1900 | 埃米利奧·薩爾加里 | null | null |
Il giorno della civetta | 1961 | 萊昂納多·夏夏 | null | null |
A ciascuno il suo | 1966 | 萊昂納多·夏夏 | null | null |
伊夫·馬蒂亞·帕斯卡 | 1904 | 路易吉·皮蘭德羅 | 1867 | 阿格里真托 |
我馬拉沃利亞 | 1881 | 喬瓦尼·維爾加 | 1840 | 維齊尼 |
請注意,不在books
表中的作者不在此連接表中。這是因為,正如我之前所說,只保留左表(在本例中books
)中不相關(guān)的行,而不是右/第二個表中的行。
更復(fù)雜的 LEFT JOIN 示例
讓我們看看另一種可以JOIN與其他 SQL 功能一起使用來進(jìn)行數(shù)據(jù)分析的方法。
您可能想查看數(shù)據(jù)庫中存在每位作者的圖書數(shù)量。您可以使用以下查詢來執(zhí)行此操作:
SELECT authors.name AS author_name,
SUM(
CASE
WHEN books.title LIKE '%'
THEN 1
ELSE 0
END
) as number_of_books
FROM authors
LEFT JOIN books
ON books.author_name = authors.name
GROUP BY authors.name
ORDER BY number_of_books DESC
;
代碼分解
第 1 行:SELECT
在結(jié)果表中列出所需的列。
第 2 行:?SUM
?是與 GROUP BY 結(jié)合使用的聚合函數(shù)。然后將組合在一起的行的值相加。
第 3-7 行:您使用?CASE 語句
?根據(jù)條件獲得不同的結(jié)果。在這種情況下,如果一行包含書名,則計為 1,否則計為 0。這里我們LIKE
用來檢查單元格是否包含任何字符。
第 8 行:這給出了number_of_books
為 SUM 創(chuàng)建的列的名稱。
第 9 行:本例中的左/第一個表是authors
。
第 10 行:本例中右側(cè)/第二個表是books
。
第 11 行:這將使用作者姓名連接兩個表。
第 12 行:行按作者姓名分組- 該列中具有相同值的所有行將由一行表示。
第 13 行:我們使用order by使用書籍?dāng)?shù)量降序排列。
該查詢將為您提供下表。請注意,在此處只能看到authors
表中的作者。books
表中提到的沒有authors
表中條目的作者在此不存在。這是books
表中不相關(guān)的行沒有保留這一事實的結(jié)果。
authors
表更新為包括books
表中提到的所有作者,如下所示:AUTHOR_NAME | NUMBER_OF_BOOKS |
---|---|
路易吉·皮蘭德羅 | 2 |
喬瓦尼·維爾加 | 1 |
切薩雷·帕韋塞 | 0 |
朱塞佩·托馬西·迪·蘭佩杜薩 | 0 |
伊塔洛·斯韋沃 | 0 |
AUTHOR_ID | NAME | YEAR_OF_BIRTH | PLACE_OF_BIRTH | TRIVA |
---|---|---|---|---|
1 | 路易吉·皮蘭德羅 | 1867 | 阿格里真托 | 1934年諾貝爾文學(xué)獎 |
2 | 喬瓦尼·維爾加 | 1840 | 維齊尼 | 1920年至1922年任意大利王國參議員 |
3 | 伊塔洛·斯韋沃 | 1861 | 的里雅斯特 | 真名是Aron Hector Schmitz |
4 | 切薩雷·帕韋塞 | 1908 | 圣斯特凡諾貝爾博 | nulll |
5 | 朱塞佩·托馬西·迪·蘭佩杜薩 | 1896 | 巴勒莫 | 1934年至1957年任蘭佩杜薩王子 |
6 | 伊塔洛·卡爾維諾 | 1923 | 圣地亞哥·德·拉斯維加斯 | nulll |
7 | 埃米利奧·薩爾加里 | 1862 | 維羅納 | nulll |
8 | 萊昂納多·夏夏 | 1921 | 拉卡爾穆托 | nulll |
那么上面查詢中的表格實際上會給出所有作者的書籍?dāng)?shù)量。
AUTHOR_NAME | NUMBER_OF_BOOKS |
---|---|
萊昂納多·夏夏 | 2 |
路易吉·皮蘭德羅 | 2 |
埃米利奧·薩爾加里 | 1 |
喬瓦尼·維爾加 | 1 |
喬瓦尼·維爾加 | 1 |
切薩雷·帕韋塞 | 0 |
朱塞佩·托馬西·迪·蘭佩杜薩 | 0 |
伊塔洛·斯韋沃 | 0 |
結(jié)論
在關(guān)系型數(shù)據(jù)庫中,數(shù)據(jù)應(yīng)該只寫一次,所以我們經(jīng)常會得到多個相互關(guān)聯(lián)的表。?LEFT JOIN
?AUTHOR_NAME當(dāng)我們需要分析來自不同表的數(shù)據(jù)和連接信息時,它是一個非常有用的盟友。享受使用這個強(qiáng)大的工具查詢您的數(shù)據(jù)庫的樂趣。