在進行兩個表乃至多個表進行聯接時需要on條件進行匹配,很多時候我們會對過濾條件放在on還是where中心存疑惑。一般來講,在外聯接中on是兩個表進行關聯的匹配條件,在該條件匹配下會生成一個虛擬表。
如:left join在根據on中的條件聯接表時,即使左邊的表(保留表)和右邊的表(非保留表)存在不匹配項(即外部行),聯接后的結果也會完整保留左邊表的內容,只是外部行在非保留表中的列都是NULL,即left join得到的結果包括內部行(匹配項)和外部行(不匹配項)。而where子句是在from子句進行處理的,這個時候如果在where子句中指定過濾條件,將得到最終需要的結果。
一言概之,on子句過濾條件不是最終的,而where子句過濾條件卻是最終的!
兩個表的基本信息分別如下(顧客信息表/訂單表):
當查詢要求為:返回在2007年2月12日下過訂單的客戶,以及他們的訂單,同時也返回在2007年2月12日沒有下過訂單的客戶。

select c.custid,c.companyname,o.orderid,o.orderdate from sales.customers as c left join sales.orders as o on o.custid=c.custid and o.orderdate='20070212';
根據紅線框的結果,將過濾條件orderdate='20070212'放在on子句中返回了在這一天下過訂單的客戶以及沒有下訂單的客戶,同時注意到上圖右下腳結果集總共有91行,也就是外聯結的結果留下的是保留表的數據,未匹配的非保留表列值為NULL。
如果查詢的要求前半句不變,后半句改為“不返回在2007年2月12日沒有下過單的客戶”。這時就需要將過濾條件orderdate=‘20070212’放在where子句中。最終的結果只有在當天沒下單的客戶數據。

select c.custid,c.companyname,o.orderid,o.orderdate from sales.customers as c left join sales.orders as o on o.custid=c.custid where o.orderdate='20070212';