2009-10-07 29 views
4

我最近發現LEFT JOIN的ON子句可能包含如(1 = 1)這樣的值。恆定值如何影響連接的ON子句?

這讓我很不高興,因爲它打破了我對加入功能的看法。

我遇到的以下情況更詳盡的版本:

SELECT DISTINCT Person.ID, ... 
FROM Person LEFT JOIN Manager 
ON (Manager.ID = Person.ID OR Manager.ID = -1)) 
WHERE (...) 

這是完全合法的。什麼「Manager.ID = -1」完成了,如果有的話?這如何影響加入?

回答

5

如果人表:

id name 

1 Person One 
2 Person Two 
3 Person Three 
4 Person Four 
5 Person Five 

如果經理表

id name 
-1 Admin 
2 Manager One 
3 Manager Two 

如果查詢:

SELECT DISTINCT * 
FROM Person LEFT JOIN Manager 
ON (Manager.id = Person.id OR Manager.id = -1) 

那麼結果是:

Person One -1 Admin 
Person Two -1 Admin 
Person Two 2 Manager One 
Person Three -1 Admin 
Person Three 3 Manager Two 
Person Four -1 Admin 
Person Five -1 Admin 

這裏所有的人行與-1管理員(在管理表)連接,如果同一ID在管理表中存在一個更加入發生。

+1

錯過「人四」浪費了我5分鐘:) – 2013-10-11 07:55:44

5

除非Manager表中的ID等於-1的行中存在一行,否則它什麼也不做。如果有這樣一行,那麼該行將始終與人表中的每一行相連。所以,每個人行,你會獲得潛在查詢輸出兩個羅斯,一個具有manager.id =到人的ID,而另一個與Manager.ID = -1排

+0

簡單的比我想象。謝謝。 – 2009-10-07 23:28:32

5

您還會看到用於進一步過濾記錄的AND子句。在處理外連接時,這非常重要,因爲將這些過濾操作添加到caluse將從左連接變爲內連接的位置(除非它類似於t.idfield爲空的地方)。

下面我將展示這是如何工作的以及爲什麼將過濾類放在正確的位置非常重要。

創建表#TEST(test1id INT,測試VARCHAR(10)) 創建表#test2的(test2id INT,test1id INT,test2的VARCHAR(10))

insert into #test (test1id, test) 
select 1, 'Judy' 
union all 
select 2, 'Sam' 
union all 
select 3, 'Nathan' 

insert into #test2 (test2id, test1id, test2) 
select 1,1,'hello' 
union all 
select 2,1,'goodbye' 
union all 
select 3,2,'hello' 

select * from #test t 
left join #test2 t2 on t.test1id = t2.test1id 
where test2 = 'goodbye' 
--result set 
--test1id test test2id test1id test2 
--1 Judy 2 1 goodbye 

select * from #test t 
left join #test2 t2 on t.test1id = t2.test1id 
and test2 = 'goodbye' 
--result set 
--test1id test test2id test1id test2 
--1 Judy 2 1 goodbye 
--2 Sam NULL NULL NULL 
--3 Nathan NULL NULL NULL 

您可以使用其中的一些字段空(假設你選擇的永遠不會爲空字段)搶在第一個表中的記錄,但沒有第二個像這樣:

select * from #test t 
left join #test2 t2 on t.test1id = t2.test1id 
where test2id is null 
--result set 
--test1id test test2id test1id test2 
--3 Nathan NULL NULL NULL