2011-08-24 69 views
6

我有一個想創建視圖的問題。我有兩個表加入了一個左外連接,例如tableAtableB,其中tableB是左外連接。用於左外連接的SQL where子句

我想只選擇狀態等於4的表B中的那些行,所以我將WHERE state = 4添加到我的查詢中。現在結果集被修剪很多,因爲tableB中沒有匹配行的所有行都從結果中刪除(因爲這些行的狀態不是4)。我也試過WHERE state = 4 OR state IS NULL,也沒有工作(因爲state技術上不是NULL,當沒有狀態)。

所以我需要的是WHERE語句,它只在實際存在一行時才被評估,這樣的事情是否存在?

如果沒有,我會看到兩個選項:join (SELECT * FROM tableB WHERE state = 4)而不是表B,或者使用相同的WHERE語句創建一個視圖並加入。什麼是最好的選擇性能明智?

順便說一句,這是SQL Server 2008 R2。

+1

這將是有趣的嘗試制定出爲什麼'WHERE狀態= 4或狀態NULL'不工作,因爲它應該防止LEFT JOIN被轉換成內加入。 –

+0

@Damien_The_Unbeliever - 它會給你所有來自TableA的行而不是TableB,但不會讓TableA在TableB中有匹配的行,其中狀態<> 4. http://data.stackexchange.com/stackoverflow/qt/110316/ –

+0

@ Damien_The_Unbeliever:有3個狀態:匹配狀態= 4,與狀態匹配<> 4,不匹配 – gbn

回答

6

您將條件放在on條款中。例如:

select a.this, b.that 
from TableA a 
left join TableB b on b.id = a.id and b.State = 4 
+0

啊,我不知道!謝謝! – Jasper

4

您可以將state = 4添加到連接條件。

select * 
from T1 
    left outer join T2 
    on T1.T1ID = T2.T1ID and 
     T2.state = 4 
1

比子查詢更容易擴展on子句,就像;

select * 
from TableA a 
left join 
     TableB b 
on  a.b_id = b.id 
     and b.state = 4 

從TableA的所有行會出現,只有那些從表B與國家4

SQL Server將可能執行的觀點,擴大on,並以完全相同的方式子查詢。所以表現明智,應該沒有什麼區別。

0

替代做法:(1)內部連接到表B,其中狀態等於4,(2)反連接表B,發現不存在的行;(3)聯合的結果:

SELECT A1.ID, A1.colA, B1.ColB 
    FROM tableA AS A1 
     INNER JOIN tableB AS B1 
      ON A1.ID = B1.ID 
      AND B1.state = 4 
UNION 
SELECT A1.ID, A1.colA, '{{MISSING}}' AS ColB 
    FROM tableA AS A1 
WHERE NOT EXISTS (
        SELECT * 
        FROM tableB AS B1 
        WHERE A1.ID = B1.ID 
       ); 

或者:

SELECT A1.ID, A1.colA, B1.ColB 
    FROM tableA AS A1 
     JOIN tableB AS B1 
      ON A1.ID = B1.ID 
      AND B1.state = 4 
UNION 
SELECT ID, colA, '{{NA}}' AS ColB 
    FROM tableA 
WHERE ID IN (
       SELECT ID 
       FROM tableA 
       EXCEPT 
       SELECT ID 
       FROM tableB 
      );