2017-03-08 83 views
2

加入我有四個表作爲有Select查詢ORACLE中

表的映射表

表GAM

fin_ac cif  acid  
3435853 49275  121  
1737631 78254  131 
2515535 84000  141 

表AST

acid despatch 
121  E 
131  E 
141  E 

臺手機

cif   email 
49275  xyz.com 
78254  xyz.com 
84000  xyz.com 

我要生成一個報告,我已經寫了查詢

SELECT b.cif, 
     a.old_ac, 
     a.fin_ac, 
     d.email, 
     c.despatch 
from map a, 
     gam b, 
     ast c, 
     phone d 
where a.fin_ac = b.fin_ac 
and b.acid = c.acid 
and d.cif = b.cif 
and c.DESPATCH in ('A','B','D','E') 

結果我得到的是

CIF    OLD_AC   FIN_AC   EMAIL DISPATCH  
10800049275 0140007063501 9080003435853 xyz.com  E 
10800078254 0140012522201 9080001737631 xyz.com  E 
10800084000 0140014195701 9080002515535 xyz.com  E 

現在對於一些在映射表,FIN_AC行一片空白。即使fin_ac爲NULL,我也想從map檢索所有行。我嘗試使用LEFT OUTER JOIN,但它不起作用。

+3

問題出在IN子句中。即使使用左連接,也不會獲得帶NULL值的FIN_AC,因爲對應的DESPATCH將爲NULL。 –

回答

1
WITH 
    map as (
     SELECT '07063501' AS old_ac, '3435853' AS fin_ac FROM DUAL 
     UNION ALL 
     SELECT '12522201' AS old_ac, '1737631' AS fin_ac FROM DUAL 
     UNION ALL 
     SELECT '14195701' AS old_ac, '2515535' AS fin_ac FROM DUAL 
     UNION ALL 
     SELECT '14195702' AS old_ac, NULL AS fin_ac FROM DUAL 
    ), 
    gam as (
     SELECT '3435853' AS fin_ac, 49275 AS cif, 121 AS acid FROM DUAL 
     UNION ALL 
     SELECT '1737631' AS fin_ac, 78254 AS cif, 131 AS acid FROM DUAL 
     UNION ALL 
     SELECT '2515535' AS fin_ac, 84000 AS cif, 141 AS acid FROM DUAL 
    ), 
    ast as (
     SELECT 121 AS acid, 'E' AS despatch FROM DUAL 
     UNION ALL 
     SELECT 131 AS acid, 'E' AS despatch FROM DUAL 
     UNION ALL 
     SELECT 141 AS acid, 'E' AS despatch FROM DUAL 
    ), 
    phone as (
     SELECT 49275 AS cif, 'xyz.com' AS email FROM DUAL 
     UNION ALL 
     SELECT 78254 AS cif, 'xyz.com' AS email FROM DUAL 
     UNION ALL 
     SELECT 84000 AS cif, 'xyz.com' AS email FROM DUAL 
    ) 
SELECT 
    b.cif, 
    a.old_ac, 
    a.fin_ac, 
    d.email, 
    c.despatch 
FROM 
    map a, 
    gam b, 
    ast c, 
    phone d 
WHERE 
    a.fin_ac = b.fin_ac(+) AND 
    b.acid = c.acid(+) AND 
    b.cif = d.cif(+) AND 
    NVL(c.DESPATCH, 'A') IN ('A','B','D','E') 
+0

您的解決方案假定FIN_AC存在於GAM中,但不在MAP中。這不是那個說的。 「對於映射表中的某些行,FIN_AC是NULL,即使fin_ac爲NULL,我也想從映射中檢索所有行。」所以他們希望當MAP.FIN_AC爲空時返回MAP記錄。您的查詢不處理這種情況。 – APC

+0

哦,你是對的,我很抱歉,我錯過了。謝謝。 – Ming

+0

@APC要清楚,我想要map.fin_ac爲空但gam.fin_ac不爲null的所有映射記錄。其實在gam fin_ac不會爲空 – Vishal5364

3

外連接的問題是,如果MAP.FIN_AC爲null,它不會連接到GAM,並且所有其他連接都依賴於GAM。所以沒有從AST檢索的記錄,這意味着DESPATCH爲空。然而,你的WHERE子句限制DESPATCH的值,所以NULL會失敗IN標準。

一個解決方案是讓AST成爲內聯查詢,並帶有過濾器。我使用ANSI SQL 92語法,因爲我認爲它使外連接更容易理解。

「我希望所有的地圖記錄,其中map.fin_ac爲空,但gam.fin_ac不爲null。其實在GAM fin_ac永遠不能爲null」

不知道挺你想要什麼,但也許MAP和GAM之間的全外連接將提供您要查找的結果?這是一種僅適用於ANSI 92語法的解決方案。

SELECT b.cif, 
     a.old_ac, 
     a.fin_ac, 
     d.email, 
     c.despatch 
from map a 
    full outer join gam b 
      on a.fin_ac = b.fin_ac 
     left join (select acid, despatch from ast 
        where DESPATCH in ('A','B','D','E')) c 
      on b.acid = c.acid 
     left join phone d 
     on d.cif = b.cif 
+0

它還提供了發送不等於( 'A', 'B', 'd', 'E') – Vishal5364