SQL語句中連接on條件和where條件的執(zhí)行順序

緣起

首先,來看下面的SQL查詢語句

select 
 *
from a left join b on a.id = b.a_id
where b.name='apple'

我期望的結(jié)果是:表a的數(shù)據(jù)全部展示出來,然后,過濾掉不符合表b條件的結(jié)果。
上面的期望結(jié)果,說的混亂不堪,腦袋一片漿糊。應(yīng)該是:

我期望的結(jié)果是:表a的數(shù)據(jù)全部展示出來,不符合表b條件的數(shù)據(jù)字段用null填充。

但是,答案卻出乎我的意料,所有數(shù)據(jù)都被過濾掉了,最終結(jié)果并不符合left join的語義,表a是主表,無論如何是應(yīng)該展示出來的,但是并沒有。
問題出在哪里呢?

原理分析

這里牽扯到的是sql語句中on后的條件和where后的條件的執(zhí)行順序問題。

數(shù)據(jù)庫在通過連接兩張或多張表返回記錄時(shí),首先根據(jù)連接條件生成一張臨時(shí)表,然后,where條件過濾臨時(shí)表,最后,將結(jié)果返回給用戶。
這里就說的很明白了,SQL語句執(zhí)行先使用on條件,然后,使用where條件。

這里,有必要再次明確一下left join...on... 語法的準(zhǔn)確含義。

LEFT JOIN 關(guān)鍵字從左表(table1)返回所有的行,即使右表(table2)中沒有匹配。如果右表中沒有匹配,則右表結(jié)果用 NULL填充。
展開來解釋一下就是:左表是主表,總是全部返回,而右表的結(jié)果是根據(jù)on條件來決定的。如果on條件為真,那么,就返回匹配上的右表結(jié)果,如果on條件為假,那么就把右表的結(jié)果用null填充。
這里的on條件不僅限于一個(gè),也可以是多個(gè)。

有了上面的基礎(chǔ)知識(shí),就可以進(jìn)一步去理解闡述了。

  • 如果b.name='apple'作為where條件,那么,按照sql語句的執(zhí)行流程,首先生成連接查詢臨時(shí)表結(jié)果,這一步是沒有問題的,然后使用where條件過濾,這時(shí)候,b表中并沒有符合條件的數(shù)據(jù),這樣,所有數(shù)據(jù)就被過濾掉了。返回的結(jié)果,就不符合預(yù)期了。
  • 如果b.name='apple'作為on條件,那么,按照sql語句的執(zhí)行流程,首先生成連接查詢臨時(shí)表結(jié)果,這一步也是沒有問題的,依然,能達(dá)到我們的預(yù)期。

總結(jié)

有時(shí)候,很簡(jiǎn)單的問題,卻并不簡(jiǎn)單?;仡^看,還是對(duì)基礎(chǔ)概念把握的不夠明晰,有模糊的地方。
這里的on條件和where條件的作用是完全不同的。on條件不具備過濾作用,只做判斷。而where條件不僅做判斷,還要對(duì)結(jié)果進(jìn)行過濾。

參考自:https://www.cnblogs.com/dancesir/p/7600265.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容