【问题标题】:oracle -left outer join ANSI queryoracle -left 外连接 ANSI 查询
【发布时间】:2010-11-15 08:46:00
【问题描述】:

我正在使用 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 代码的记录。下面是较旧的左外连接语法:

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代码有问题吗??

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您使用的是 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'
    

    【讨论】:

      【解决方案2】:

      在我看来你的语法是错误的。

      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 的加入中消除任何东西?

      罗伯

      【讨论】:

        猜你喜欢
        • 2014-07-08
        • 1970-01-01
        • 1970-01-01
        • 2019-11-18
        • 1970-01-01
        • 2012-08-31
        • 2017-04-08
        • 2021-12-28
        • 1970-01-01
        相关资源
        最近更新 更多