SQL中的查詢連接有 inner join(內(nèi)連接),left join(左連接),right join(右連接),full join(全連接)四種方式,這四種查詢方式的區(qū)別不大,只是查詢的結(jié)果不一樣。
現(xiàn)在有“Person”表和“Orders”表:
Person:

Orders:

對于Orders表,通過Id_P字段和Person表關(guān)聯(lián)。
inner join
在兩張表進(jìn)行連接查詢時(shí),只保留兩張表中完全匹配的結(jié)果
跟 SQL 的where 語句類似
sql如下:
SELECT a.LastName, a.FirstName, b.OrderNo
FROM Persons as a
INNER JOIN Orders as b
ON a.Id_P=b.Id_P
ORDER BY a.LastName
查詢結(jié)果集:

此種連接方式Orders表中Id_P字段在Persons表中找不到匹配的,則不會(huì)列出來。
left join
在兩張表進(jìn)行連接查詢的時(shí)候,以左表為主表,會(huì)返回左表中所有的行,哪怕on中的條件不為真,也即是在右表中沒有匹配的記錄
sql如下:
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName
結(jié)果集如下:

從結(jié)果集中可以看到,左表(Person表)中LastName為Bush的行的Id_P字段在右表(Orders表)中沒有匹配,但是查詢結(jié)果仍然保留該行。
right join
在兩張表進(jìn)行連接查詢的時(shí)候,以右表為主表,會(huì)返回右表所有的行,即使在左表中沒有匹配的記錄,恰好和left join(左連接)是相反的
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
RIGHT JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName
查詢結(jié)果集如下:

Orders表中最后一條記錄Id_P字段值為65,在左表中沒有記錄與之匹配,但依然保留。
full join
在兩張表進(jìn)行連接查詢時(shí),返回左表和右表中所有匹配的行,和所有沒有匹配的行。
相當(dāng)于是 left join 和 right join 的并集。
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
FULL JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName
查詢結(jié)果集如下:

數(shù)據(jù)庫在通過連接兩張或多張表來返回記錄時(shí),都會(huì)生成一張中間的臨時(shí)表,然后再將這張臨時(shí)表返回給用戶。
而在使用這四種連接方式的時(shí)候,on和where條件的區(qū)別如下:
on 條件是在生成臨時(shí)表的時(shí)候使用的條件,根據(jù)on中的條件,還有連接的方式返回主表中的記錄,生成相應(yīng)臨時(shí)表。
where 條件是在臨時(shí)表生成好后,再對臨時(shí)表進(jìn)行過濾的條件,這時(shí)候已經(jīng)沒有了查詢連接的含義了,是對臨時(shí)表中的數(shù)據(jù)進(jìn)行過濾,條件不為真的數(shù)據(jù)就全部過濾。
多張表聯(lián)立查詢,多個(gè)left join 或right join,其實(shí)就是相當(dāng)于是以主表為主,以不同的on條件,不斷的拼接符合條件的數(shù)據(jù),拼接出符合要求的臨時(shí)表,最后再以where條件,對整個(gè)臨時(shí)表進(jìn)行過濾。
現(xiàn)在有“tab1”表和“tab2”表:

tab2:

兩條SQL:
select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)
對于第一條SQL執(zhí)行的過程:

對于第二條SQL執(zhí)行的過程:

其實(shí)以上結(jié)果的關(guān)鍵原因就是left join,right join,full join的特殊性,不管on上的條件是否為真都會(huì)返回left或right表中的記錄,full則具有l(wèi)eft和right的特性的并集。 而inner jion沒這個(gè)特殊性,則條件放在on中和where中,返回的結(jié)果集是相同的。