2015-12-01 17 views
3

我不得不解決一個查詢,在做右連接與右手側的附加約束:RIGHT JOIN b ON b.key = a.key AND b.active = 'Y'在SQL正確連接中加入約束是否可以做任何事情?

它似乎完全忽視了b.active約束。這是RIGHT JOIN的限制嗎?我換了桌子,把約束移到了WHERE,我從來不喜歡RIGHT JOIN,我認爲這加強了我對它的厭惡。

回答

5

這個查詢:

SELECT . . . 
FROM a RIGHT JOIN 
    b 
    ON b.key = a.key AND b.active = 'Y' 

是一樣的:

SELECT . . . 
FROM b LEFT JOIN 
    a 
    ON b.key = a.key AND b.active = 'Y' 

在這兩種情況下,「駕駛」表外連接上有一個條件。即使當ON條件未評估爲真時,左/右外連接的邏輯也會將所有記錄保留在一個表中。因此,該表上的條件不會導致任何過濾。

如果你想在該表進行篩選,然後用WHERE條款:

SELECT . . . 
FROM a RIGHT JOIN 
    b 
    ON b.key = a.key 
WHERE b.active = 'Y' 

我還應該注意的是,以下兩個查詢是相當於:

SELECT . . . 
FROM a RIGHT JOIN 
    b 
    ON b.key = a.key AND b.active = 'Y'; 

SELECT . . . 
FROM a RIGHT JOIN 
    b 
    ON b.key = a.key; 

他們返回假設沒有重複鍵b。但是,當b.active不是'Y'時,第二個將返回a中的匹配行。在這種情況下,第一個將返回a中的列的NULL值。這是一個微妙的區別。說實話,我認爲我從來沒有發現太多用處。

+1

SQL中的「左外連接」和「右外連接」構造一直是我的痛處。實際上只有兩種外連接:「全外連接」和「部分外連接」。左右分別引入了一個錯誤的概念。這就好像注意到,由於分工不可交換(如部分外連接),我們應該有「/」 - 正確的分工,「\」 - 左分工;唯一的區別是分子和分母的順序是相反的。這種分割是荒謬的 - 對於關係型外連接來說是荒謬的。 –

+0

@KenClement。 。 。 SQL語句不是關係代數。 「FROM」子句按照寫入表的順序進行語義處理(或由括號指定)。由於這種處理的性質,SQL作爲一種語言需要區分哪個是「部分」外連接的「驅動」表。爲了這個目的,「左」和「右」對我來說意義重大(儘管坦率地說,我很高興能夠消除「右連接」)。 –

+0

@Gordon ...你依賴的錯誤理解可能是基於在一個熟悉的實現。實際上並不是所有的SQL實現都有一個「驅動表」的概念,它們在內部如何實現查詢計劃,至少沒有列出任何綁定到訂單表的列表。這個概念不是SQL固有的。沒有,我再說一遍,有充分的理由讓除了語法糖之外的「右」和「左」外連接。無論連接的類型如何,都從左到右連接。左側和右側部分外部連接僅在操作數(表)的順序上有所不同。 「不是代數」是一種紅鯡魚。 –

相關問題