oracle -left外连接ANSI查询

时间:2009-07-30 08:21:49

标签: sql oracle

我正在使用Oracle ANSI左外连接语法执行以下查询,它返回107条记录:

SELECT  bs_accts.acct_num,  
          bs_accts.acct_name,  
          br_data.record_id ,  
       as_users.username,   
       br_fx.fx_rate ,  
FROM    bs_accts
CROSS JOIN as_users  
CROSS JOIN br_fx
left outer join br_data 
ON (as_users.userid = br_data.last_note_user AND br_fx.iso_src = br_data.user_ten)
WHERE   br_data.state=3       
AND (br_data.acct_id  = bs_accts.acct_id) 
AND (bs_accts.acct_currency='SHS')        
AND     substr(bs_accts.acct_num,1,1)='T'     
AND br_fx.iso_dst = 'USD';

当我执行没有ANSI语法的相同查询时它返回875条记录。我想要875条带有ANSI代码的记录.Below是旧的左外连接语法:

SELECT  bs_accts.acct_num,  
          bs_accts.acct_name,  
          br_data.record_id ,  
       as_users.username,   
       br_fx.fx_rate ,  
FROM    bs_accts,as_users,br_fx,br_data
WHERE   br_data.state=3       
AND (br_data.acct_id  = bs_accts.acct_id) 
AND (bs_accts.acct_currency='SHS')        
AND     substr(bs_accts.acct_num,1,1)='T'
AND     br_data.last_note_user=as_users.userid(+)  
AND br_data.user_ten = br_fx.iso_src(+) 
AND br_fx.iso_dst = 'USD';

上面的ANSI代码有什么问题吗?

2 个答案:

答案 0 :(得分:2)

你正在使用CROSS JOIN,而不是LEFT OUTER JOIN,所以它绝对不是同一个查询。

您的旧式语法查询是错误的,或者至少不包含您可能认为的br_fx的外连接,因为此部分缺少(+)符号:

AND br_fx.iso_dst = 'USD'

该条件否定了

上使用的(+)
AND br_data.user_ten = br_fx.iso_src(+) 

所以也许你的意思是:

AND br_fx.iso_dst(+) = 'USD'

答案 1 :(得分:0)

我认为你的语法错了。

AND     br_data.last_note_user=as_users.userid(+)  
AND br_data.user_ten = br_fx.iso_src(+) 

...意味着您保留br_data中的所有行,即使它们在其他行中没有匹配项也是如此。这就像在第一个查询中使用RIGHT JOIN一样。

实际上,WHERE子句删除LEFT JOIN引入的任何NULL,使您的OUTER JOIN成为INNER连接。

left outer join br_data 
ON (as_users.userid = br_data.last_note_user AND br_fx.iso_src = br_data.user_ten)
WHERE   br_data.state=3     

我真的希望您通过查询告诉我们您真正想要的内容。

这是吗?

SELECT  bs_accts.acct_num,  
          bs_accts.acct_name,  
          br_data.record_id ,  
       as_users.username,   
       br_fx.fx_rate
FROM  
   br_data
   join
   bs_accts 
      on (br_data.acct_id  = bs_accts.acct_id) 
      AND (bs_accts.acct_currency='SHS')        
      AND substr(bs_accts.acct_num,1,1)='T'
      AND br_data.state=3       
   LEFT JOIN
   as_users
      ON br_data.last_note_user=as_users.userid
   LEFT JOIN
   br_fx
      ON br_data.user_ten = br_fx.iso_src
      AND br_fx.iso_dst = 'USD';

...你想要br_data和bs_accts加入(在所有那些不同的东西上),然后挂钩到as_users和br_fx,但是没有从br_data和bs_accts的连接中删除任何东西?

罗布