【左連接和內(nèi)連接的區(qū)別】寫 SQL 語(yǔ)句時(shí),`LEFT JOIN`和 `INNER JOIN` 是最容易讓人在數(shù)據(jù)結(jié)果上“踩坑”的兩個(gè)關(guān)鍵字。很多時(shí)候,業(yè)務(wù)邏輯看似一樣,查出來(lái)的數(shù)據(jù)卻天差地別。其實(shí)核心就一句話:你要的是“交集”,還是“以主表為主的全量”?
為了不讓腦袋打架,咱們直接拿兩個(gè)最典型的場(chǎng)景來(lái)盤一盤。想象你手里有兩個(gè)表:表 A(比如訂單表)和表 B(比如用戶表)。
如果用內(nèi)連接(INNER JOIN),它是個(gè)“強(qiáng)迫癥”。它只關(guān)心兩邊都能對(duì)上號(hào)的數(shù)據(jù)。如果訂單 A 找不到對(duì)應(yīng)的用戶 ID,這條記錄直接消失;反之,如果一個(gè)用戶下了單但表里沒(méi)記下來(lái),那這個(gè)用戶也不顯示在內(nèi)連接的結(jié)果里。結(jié)論就是:只有雙方都存在的數(shù)據(jù),才會(huì)被保留,否則統(tǒng)統(tǒng)過(guò)濾掉。
而左連接(LEFT JOIN)則更像是一個(gè)“護(hù)短者”。它的名字里有“左”,意味著左邊的表是老大。無(wú)論右邊的表有沒(méi)有匹配上的數(shù)據(jù),左邊表里的每一行都必須出現(xiàn)。如果右邊沒(méi)找到對(duì)應(yīng)項(xiàng),那就用 `NULL` 填坑。結(jié)論是:左邊的底細(xì)全得露出來(lái),右邊配不配得上,無(wú)所謂。
很多初學(xué)者容易犯的一個(gè)錯(cuò)誤是:以為加了左連接就一定能查出所有數(shù)據(jù),結(jié)果在后面加了一個(gè)針對(duì)右表的 `WHERE` 條件,瞬間把左連接變成了內(nèi)連接。這是因?yàn)?`WHERE` 會(huì)先把數(shù)據(jù)跑一遍再篩選,這時(shí)候 `NULL` 值往往就被當(dāng)成“假”給過(guò)濾掉了。所以,處理這種跨表查詢的邏輯,最好在 `ON` 后面限定條件,而不是最后用 `WHERE` 兜底。
下面這張表總結(jié)了它們的核心差異,方便日常查閱對(duì)比:
| 比較維度 | 內(nèi)連接 (INNER JOIN) | 左連接 (LEFT JOIN) |
| : | : | : |
| 保留邏輯 | 僅保留兩表關(guān)聯(lián)字段相等的記錄 | 保留左表全部記錄,右表若無(wú)匹配則為空 |
| 數(shù)據(jù)去重性 | 相當(dāng)于求交集,無(wú)匹配則丟棄 | 以左表為主軸,非匹配項(xiàng)不會(huì)導(dǎo)致左表丟失 |
| 返回行數(shù) | 通常較少(等于交集大小) | 通常較多(至少等于左表行數(shù)) |
| NULL 值處理 | 結(jié)果集中不會(huì)出現(xiàn)因未匹配產(chǎn)生的 NULL | 未匹配的右表字段顯示為 NULL |
| 典型場(chǎng)景 | 需要查找“既存在又相關(guān)”的數(shù)據(jù) | 需要排查“有哪些可能缺失關(guān)聯(lián)”的主數(shù)據(jù) |
| 性能消耗 | 相對(duì)優(yōu)化較好(因?yàn)樘蕹啵? | 視數(shù)據(jù)量而定,若右表很大需警惕笛卡爾積風(fēng)險(xiǎn) |
實(shí)際開發(fā)中,怎么選主要看你的目的。如果你要統(tǒng)計(jì)“有訂單的用戶”,內(nèi)連接更合適,省去了后續(xù)清洗數(shù)據(jù)的麻煩。但如果你是做報(bào)表,想知道“有多少潛在用戶還沒(méi)產(chǎn)生訂單”,那你必須用左連接,這樣才能看到那些右邊空空如也的“幽靈數(shù)據(jù)”。記住,SQL 不僅是技術(shù)操作,更是業(yè)務(wù)邏輯的直接翻譯,理解這兩個(gè)連接的本質(zhì),往往比死記語(yǔ)法更重要。


