2015-04-01 24 views
0

如果我運行下面的查詢查詢:替代辦法離開加入SQL Oracle數據庫

SELECT day.M_CMP_TYPO AS M_CMP_TYPO, 
     day.M_SPTCV as M_SPTCV, 
     day.M_CNT_VS2 AS M_CNT_VS2, 
     day.M_CNT_ORG AS M_CNT_ORG, 
     day.M_PL_CGR2 AS M_PL_CGR2, 
     day.M_PL_CGU2 AS M_PL_CGU2, 
     day.M_PL_CSFI2 AS M_PL_CSFI2, 
     day.M_PL_FTFI2 AS M_PL_FTFI2, 
     day.M_PL_RVR2 AS M_PL_RVR2, 
     day.M_PL_RVU2 AS M_PL_RVU2, 
     day.M_TRN_FMLY AS M_TRN_FMLY, 
     day.M_TRN_GRP AS M_TRN_GRP, 
     day.M_TRN_TYPE AS M_TRN_TYPE, 
     day.M_CNT_VS2 AS M_CNT_VS2, 
     day.M_C_CUR_PL AS M_C_CUR_PL, 
     day.M_INSTRLABEL AS M_INSTRLABEL, 
     day.M_NB AS M_NB, 
     day.M_PL_INSCUR AS M_PL_INSCUR, 
     day.M_TP_CNTRPLB AS M_TP_CNTRPLB, 
     day.M_TP_PFOLIO AS M_TP_PFOLIO, 
     day.M_ECO_PL AS M_ECO_PL, 
     day.M_CNT_ID AS M_CNT_ID, 
     day.M_ECO_PL_USD AS M_ECO_PL_USD, 
     day.M_POS_CURR2 AS M_POS_CURR2, 
     day.M_CURR2 AS M_CURR2, 
     day.M_TP_QTYEQ AS M_TP_QTYEQ, 
     day.M_TP_UQTYEQ AS M_TP_UQTYEQ, 
     day.M_TP_LQTY32 AS M_TP_LQTY32, 
     day.M_TP_UQTY AS M_TP_UQTY, 


    --day.M_ECO_PL - daily.M_ECO_PL AS DAILY_VAR, 
     --day.M_ECO_PL - month.M_ECO_PL AS MTD, 
    day.M_ECO_PL - year.M_ECO_PL AS YTD, 



--day.M_SPTCV * (day.M_ECO_PL - daily.M_ECO_PL) as DAILY_VAR_USD, 
--day.M_SPTCV * (day.M_ECO_PL - month.M_ECO_PL) as MTD_USD, 
day.M_SPTCV * (day.M_ECO_PL - year.M_ECO_PL) as YTD_USD 



    FROM RT_PLVAR_REP day 
    LEFT JOIN RT_PLVAR_REP year ON day.M_NB = year.M_NB 
    --LEFT JOIN RT_PLVAR_REP month ON day.M_NB = month.M_NB 
    --LEFT JOIN RT_PLVAR_REP daily ON day.M_NB = daily.M_NB 

WHERE day.M_REF_DATA = 18 
AND year.M_REF_DATA = 20 
--AND month.M_REF_DATA = 0 
--AND daily.M_REF_DATA = 0 

返回預期的行爲,這意味着它返回27行明知year.M_REF_DATA = 20存在於DB 。否則,如果我運行這個我沒有任何價值。 由於表中不存在M_REF_DATA = 0,我期待這個查詢返回27行,但相關的列應該返回null,但事實並非如此。

我試圖用AND代替它,它也沒有工作。它返回1728行,這是一個錯誤的答案,它應該返回11.我的問題是爲什麼左連接不工作,因爲我期待?

SELECT day.M_CMP_TYPO AS M_CMP_TYPO, 
      day.M_SPTCV as M_SPTCV, 
      day.M_CNT_VS2 AS M_CNT_VS2, 
      day.M_CNT_ORG AS M_CNT_ORG, 
      day.M_PL_CGR2 AS M_PL_CGR2, 
      day.M_PL_CGU2 AS M_PL_CGU2, 
      day.M_PL_CSFI2 AS M_PL_CSFI2, 
      day.M_PL_FTFI2 AS M_PL_FTFI2, 
      day.M_PL_RVR2 AS M_PL_RVR2, 
      day.M_PL_RVU2 AS M_PL_RVU2, 
      day.M_TRN_FMLY AS M_TRN_FMLY, 
      day.M_TRN_GRP AS M_TRN_GRP, 
      day.M_TRN_TYPE AS M_TRN_TYPE, 
      day.M_CNT_VS2 AS M_CNT_VS2, 
      day.M_C_CUR_PL AS M_C_CUR_PL, 
      day.M_INSTRLABEL AS M_INSTRLABEL, 
      day.M_NB AS M_NB, 
      day.M_PL_INSCUR AS M_PL_INSCUR, 
      day.M_TP_CNTRPLB AS M_TP_CNTRPLB, 
      day.M_TP_PFOLIO AS M_TP_PFOLIO, 
      day.M_ECO_PL AS M_ECO_PL, 
      day.M_CNT_ID AS M_CNT_ID, 
      day.M_ECO_PL_USD AS M_ECO_PL_USD, 
      day.M_POS_CURR2 AS M_POS_CURR2, 
      day.M_CURR2 AS M_CURR2, 
      day.M_TP_QTYEQ AS M_TP_QTYEQ, 
      day.M_TP_UQTYEQ AS M_TP_UQTYEQ, 
      day.M_TP_LQTY32 AS M_TP_LQTY32, 
      day.M_TP_UQTY AS M_TP_UQTY, 


     day.M_ECO_PL - daily.M_ECO_PL AS DAILY_VAR, 
      day.M_ECO_PL - month.M_ECO_PL AS MTD, 
     day.M_ECO_PL - year.M_ECO_PL AS YTD, 



    day.M_SPTCV * (day.M_ECO_PL - daily.M_ECO_PL) as DAILY_VAR_USD, 
    day.M_SPTCV * (day.M_ECO_PL - month.M_ECO_PL) as MTD_USD, 
    day.M_SPTCV * (day.M_ECO_PL - year.M_ECO_PL) as YTD_USD 



     FROM RT_PLVAR_REP day 
     LEFT JOIN RT_PLVAR_REP year ON day.M_NB = year.M_NB 
     LEFT JOIN RT_PLVAR_REP month ON day.M_NB = month.M_NB 
     LEFT JOIN RT_PLVAR_REP daily ON day.M_NB = daily.M_NB 

    WHERE day.M_REF_DATA = 18 
    AND year.M_REF_DATA = 0 
    AND month.M_REF_DATA = 0 
    AND daily.M_REF_DATA = 0 
+0

通過在您的WHERE中說'year.M_REF_DATA = 0',您要求該值存在。考慮將AND移到它們各自的ON之下,否則將該子句包含在定義如何處理NULL的邏輯中。例如:'NVL(year.M_REF_DATA,0)= 0'。 – 2015-04-01 17:03:38

回答

5

這是從第一查詢的fromwhere子句:

FROM RT_PLVAR_REP day LEFT JOIN 
    RT_PLVAR_REP year 
    ON day.M_NB = year.M_NB 
WHERE day.M_REF_DATA = 18 AND year.M_REF_DATA = 20 

where子句轉動LEFT JOININNER JOINyear.M_REF_DATA的值爲NULL,所以它不符合條件。

對於LEFT JOIN,條件應該去ON子句中:

FROM RT_PLVAR_REP day LEFT JOIN 
    RT_PLVAR_REP year 
    ON day.M_NB = year.M_NB AND year.M_REF_DATA = 20 
WHERE day.M_REF_DATA = 18 

條件在第一個表應該留在WHERE

0

對於外連接,您需要將過濾條件移到加盟:

FROM RT_PLVAR_REP day 
    LEFT JOIN RT_PLVAR_REP year 
    ON day.M_NB = year.M_NB 
     AND year.M_REF_DATA = 0 
    LEFT JOIN RT_PLVAR_REP month 
    ON day.M_NB = month.M_NB 
     AND month.M_REF_DATA = 0 
    LEFT JOIN RT_PLVAR_REP daily 
    ON day.M_NB = daily.M_NB 
     AND daily.M_REF_DATA = 0 
WHERE day.M_REF_DATA = 18 

這告訴你只想當一個行存在強制執行該標準的數據庫。