2017-08-07 111 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