2017-08-07 72 views
2

======原题======甲骨文外连接和常量值

我有多个外的常数加入如下的SQL:

select .. from CLAS MDP, CLAS ORG_CNTRY, CLAS BEN_CNTRY 
AND ORG_CNTRY.LAS_ID(+) = 'COUNTRY_LOOKUP' 
AND ORG_CNTRY.CB_DT  = MDP.CB_DT 
AND BEN_CNTRY.LAS_ID(+) = 'COUNTRY_LOOKUP' 
AND BEN_CNTRY.CB_DT  = MDP.CB_DT 

上述查询是否与下面的查询相同?请指教。

select ... from 
CLAS MDP left join CLAS ORG_CNTRY on ORG_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' left 
join CLAS BEN_CNTRY on BEN_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' where ORG_CNTRY.CB_DT  
= MDP.CB_DT and BEN_CNTRY.CB_DT  = MDP.CB_DT 

======后续问题=======

@Used_By_Already,@Gordon Linoff感谢您的答复。

但是,我的实际查询比我最初发布的要多一点。它如下所示:

MDP.CLAS_ID = 'DIS_PARAMETERS' 
AND MDP.CB_DT = <<BusinessDate>> 
AND ACCT.ACCT_NO = TXN.ACCT_NO 
AND MDP.CTRY_CD = TXN.REC_CTRY_CD 
AND TXN.CB_DT BETWEEN ACCT.START_DT and ACCT.END_DT 
AND ORG_CNTRY.CLAS_ID(+) = 'COUNTRY_LOOKUP' 
AND ORG_CNTRY.CB_DT  = MDP.CB_DT 
AND BEN_CNTRY.CLAS_ID(+) = 'COUNTRY_LOOKUP' 
AND BEN_CNTRY.CB_DT  = MDP.CB_DT 
AND TXN.SEND_CTRY_CD = ORG_CNTRY.CLAS_SCHM_CD(+) 
AND TXN.RCIP_CTRY_CD = BEN_CNTRY.CLAS_SCHM_CD(+) 

这可以重写成如下吗?请指教。

select ... 
from 
CLAS MDP left join CLAS ORG_CNTRY on ORG_CNTRY.CB_DT = MDP.CB_DT 
    AND ORG_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 
right join ACCT_TRAN TXN on ORG_CNTRY.CLAS_SCHM_CD = TXN.SEND_CTRY_CD 
left join CLAS BEN_CNTRY on BEN_CNTRY.CB_DT = MDP.CB_DT 
    AND BEN_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 
right join ACCT_TRAN TXN on BEN_CNTRY.CLAS_SCHM_CD = TXN.RCIP_CTRY_CD 
+0

号联接和过滤谓词可以在'join'条款都去了,即使分离过滤谓词出与内部连接是更符合逻辑,并把它们在'where'条款。这意味着内部和外部连接不可互换是我不喜欢的语法之一。 –

+0

存在一个非常非正式的,基本上不成文的规则,即:*“不要使用正确的外连接”*这里肯定没有理由这么做。但是,您要求确定的答案,而无需访问数据。它只能是最好的猜测,它需要进行测试。注意你**不能声明表格别名TXN两次**,这将永远不会工作。 –

回答

1

可能不是。与LEFT JOIN S中的明智查询是:

select ... 
from CLAS MDP left join 
    CLAS ORG_CNTRY 
    on ORG_CNTRY.CB_DT = MDP.CB_DT AND ORG_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' left join 
    CLAS BEN_CNTRY 
    on BEN_CNTRY.CB_DT = MDP.CB_DT AND BEN_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 

忘掉陈旧(+)语法。如前所述,我甚至不确定它是否会导致外部联接。

+0

感谢您的回复 – sandeep

+0

请问您能帮我验证一下我的方法和后续问题 – sandeep

2

这些谓词中的每一个都提到了两个表格,它们使得它们“连接条件”(而不是“过滤条件”)。

 
    AND ORG_CNTRY.CB_DT = MDP.CB_DT 
    AND BEN_CNTRY.CB_DT = MDP.CB_DT 

如果从“老土”甲骨文转换连接语法那么这些“加盟条件MUST移动到连接语法,就像这样:

select ... 
from CLAS MDP 
left join CLAS ORG_CNTRY on ORG_CNTRY.CB_DT = MDP.CB_DT 
left join CLAS BEN_CNTRY on BEN_CNTRY.CB_DT = MDP.CB_DT 

希望它现在变成清楚其他谓词(在常量上)在where子句中是没有意义的,否则外连接将被覆盖为等同于内连接。因此,这些也需要被移动到连接和你结束了:

select ... 
from CLAS MDP 
left join CLAS ORG_CNTRY on ORG_CNTRY.CB_DT = MDP.CB_DT AND ORG_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 
left join CLAS BEN_CNTRY on BEN_CNTRY.CB_DT = MDP.CB_DT AND BEN_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 

虽然下面的注释绝非强制性的,我建议先上市“前表”,在新的连接语法(注意:MDP上市之前要么其他表):where子句语法是可以从旧的(很凌乱)转换时被忽略

 
select ... 
from CLAS MDP 
left join CLAS ORG_CNTRY on MDP.CB_DT = ORG_CNTRY.CB_DT AND ORG_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 
left join CLAS BEN_CNTRY on MDP.CB_DT = BEN_CNTRY.CB_DT AND BEN_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 

一件事顺序listin FROM列表中的g表无关紧要。然而,当使用诸如的语法时,加入t2 ON t1.x = t2.y表t1必须在t2之前列出,否则连接将产生错误。我发现首先列出“先前表格”有助于确保这是真实的。


顺便说一句:在“古代语法”,你会需要以下适当地形成这两个外部联接:

select .. from CLAS MDP, CLAS ORG_CNTRY, CLAS BEN_CNTRY 
AND ORG_CNTRY.LAS_ID(+) = 'COUNTRY_LOOKUP' 
AND ORG_CNTRY.CB_DT(+)  = MDP.CB_DT 
AND BEN_CNTRY.LAS_ID(+) = 'COUNTRY_LOOKUP' 
AND BEN_CNTRY.CB_DT(+)  = MDP.CB_DT 

否则,你已经形成了内通过要求在一列值加入表等于另一个表中某个值的字段(&,因此不允许有不匹配的值)。


其他查询(多连接)

一旦你建立了一个LEFT JOIN,并且要涉及另一个表到左连接表继续使用LEFT JOIN。还要注意,每个表别名必须是唯一的,所以如果你需要多次连接任何表,请确保所使用的别名不相同。

SELECT 
     * 
FROM CLAS MDP 
LEFT JOIN CLAS ORG_CNTRY ON MDP.CB_DT = ORG_CNTRY.CB_DT AND ORG_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 
LEFT JOIN CLAS BEN_CNTRY ON MDP.CB_DT = BEN_CNTRY.CB_DT AND BEN_CNTRY.LAS_ID = 'COUNTRY_LOOKUP' 
LEFT JOIN ACCT_TRAN TXN1 ON ORG_CNTRY.CLAS_SCHM_CD = TXN1.SEND_CTRY_CD 
LEFT JOIN ACCT_TRAN TXN2 ON BEN_CNTRY.CLAS_SCHM_CD = TXN2.RCIP_CTRY_CD 
+0

您能帮我验证我的方法和后续问题吗 – sandeep