2014-06-24 121 views
0

在此代碼段:SQL留下過濾器聯接不使用過濾器

proc sql; 

    create table test3 (id numeric (10)); 
    create table test4 (id numeric (10)); 
    quit; 


    proc sql; 
    insert into test3 (id) values (1); 
    insert into test3 (id) values (2); 
    insert into test3 (id) values (2); 

    insert into test4 (id) values (1); 
    insert into test4 (id) values (2); 

    create table test5 as 
    select * from test3 left join test4 on test3.id = test4.id 

    and test3.id<> 2 and test4.id <> 2; 

    quit; 

我想從TEST3所有行,即使有上TEST4沒有匹配行,前提是ID列的值<> 2 in test3 and test4 .... aka在最終輸出中,我不想要id = 2記錄,甚至沒有一次。

但上面的加入所賜:

1 
2 
2 

彷彿<> 2過濾器是不存在的。爲什麼是這樣?

回答

1

嘗試:

create table test5 as 
select * from test3 left join test4 on test3.id = test4.id 

WHERE test3.id<> 2 and test4.id <> 2; 

你的連接語句包括and這很可能是建立一個工會。更改爲where

+0

謝謝。這有效,但也在WHERE中,如果我使用OR而不是AND,它會給出相同的(期望的)結果。這是爲什麼? – Victor

+0

在您的示例數據中,加入test3.id = test4.id然後通過test3.id <> 2或test4.id <> 2 ...進行篩選的組合等同於加入並使用AND條件。對於你的例子,這並不重要。戈登的答案有同樣的理由,可以說是對你的問題更直接的回答。 – kaliatech

+1

換一種說法,'test3.id = test4.id'的左連接與'where test3.id <> 2'確保沒有test3.id = 2記錄將被選中,然後自動意味着沒有test4.id = 2記錄也將包含在內,因爲test3是主要/左連接表。 – kaliatech

2

這是討論中的查詢:

select * 
from test3 left join 
    test4 
    on test3.id = test4.id and 
     test3.id <> 2 and test4.id <> 2; 

left join保持來自所述第一表中的所有行和任何匹配的行從第二。如果第一個表中給定行沒有匹配的行,則保留該行。

換句話說,當您執行left join時,第一個表上的on子句中的過濾器不起作用。您應該將此條件移至where子句:

select * 
from test3 left join 
    test4 
    on test3.id = test4.id and 
     test4.id <> 2 
where test3.id <> 2; 
+0

非常感謝。 – Victor