2017-06-21 77 views
0

我試圖在SQL中構建一些測試用例。問題是,當我試圖加入一個左連接表(如果我的理解是正確的,應該返回匹配和不匹配的行),當im試圖獲取沒有匹配的ID的數據時,沒有數據被返回。下面是代碼:SQL連接不返回正確的數據

select 
     E.ID_EVENEMENT, 
     t1.dateRecente as date_Star, 
     virage_c.no_contr, 
     t2.id as id_Univers, 
     t2.dateRecente as date_Univers, 
     t3.NUMERO_DOSSIER_STAR, 
     t3.dateRecente as Date_factcan, 
     t3.dateLimite, 
     t2.ID_PERSONNE_UNIVERS, 
     t1.ID_PERSONNE_STAR 
    FROM 
     STAR.EVENEMENT e 
     left join VIRAGE.CONTRAT virage_c 
      on e.NO_CONTRAT_OFFICIEL = to_char(virage_c.no_contr) 
     inner join 
     (SELECT 
       e.ID_EVENEMENT, 
       ep.ID_EVEN_INDIVIDU as ID_PERSONNE_STAR, 
       GREATEST(e.dt_creation, 
          NVL(e.DT_MODIF_STA_ELI, TO_DATE(1,'j')), 
          NVL(max(nt.dt_maj), TO_DATE(1,'j')), 
          NVL(max(ser.DT_CREATION), TO_DATE(1,'j')), 
          NVL(max(SER.DT_MAJ), TO_DATE(1,'j')), 
          NVL(max(aut.dt_transmis), TO_DATE(1,'j')), 
          NVL(max(AUT.DT_CREATION), TO_DATE(1,'j'))) dateRecente 
       FROM 
       STAR.EVENEMENT e 
        left join STAR.Note nt 
         on e.ID_EVENEMENT = nt.ID_EVEN 
        left join STAR.SERVICE ser 
         on e.ID_EVENEMENT = ser.ID_EVEN 
         left join STAR.AUTORISATION aut 
          on ser.id_service = aut.id_service 
        left join STAR.DOCUMENT doc 
         on e.ID_EVENEMENT = doc.ID_EVENEMENT 
        left join STAR.ETAT ett 
         on e.ID_EVENEMENT = ett.ID_EVENEMENT 
        left join STAR.EVENEMENT_PARTICIPANT ep 
         on e.ID_EVENEMENT = ep.ID_EVENEMENT 
       GROUP BY 
       e.ID_EVENEMENT, 
       e.dt_creation, 
       e.DT_MODIF_STA_ELI, 
       ep.ID_EVEN_INDIVIDU) t1 
       on t1.ID_EVENEMENT = E.ID_EVENEMENT 
     left JOIN 
     (SELECT 
       sf.STAREVENTNUMBER, 
       c.id, 
       par.ID as ID_PERSONNE_UNIVERS, 
       GREATEST(c.UPDATEDATE, 
          max(NVL(ca.UPDATEDATE, TO_DATE(1, 'J'))), 
          max(NVL(bo.UPDATEDATE, TO_DATE(1, 'J'))), 
          max(NVL(a.UPDATEDATE, TO_DATE(1, 'J'))), 
          max(NVL(p.UPDATEDATE, TO_DATE(1, 'J'))), 
          max(NVL(p.RELEASEDATE, TO_DATE(1, 'J'))), 
          max(NVL(p.PAYMENTDATE, TO_DATE(1, 'J')))) dateRecente 
       FROM 
       CV_CLAIMS_TRAVEL.STAR_FILE sf 
        join CV_CLAIMS_TRAVEL.CLAIM c 
         on sf.claimid = c.id 
         left join CV_CLAIMS_TRAVEL.BENEFIT_OPTION bo 
          on c.id = BO.CLAIMID 
          left join CV_CLAIMS_TRAVEL.ADJUDICATION a 
          on bo.id = a.BENEFITOPTIONID  
         left join CV_CLAIMS_TRAVEL.CLAIM_ACTIVITY ca 
          on c.id = CA.CLAIMID 
         left join CV_CLAIMS_TRAVEL.CLAIM_RELATIONSHIP cr 
          on c.id = CR.CLAIMID 
          left join CV_CLAIMS_TRAVEL.PAYEE pa 
          on cr.id = PA.CLAIMRELATIONSHIPID 
          left join CV_CLAIMS_TRAVEL.PAYMENT p 
           on pa.id = P.PAYEEID 
        left join CV_CLAIMS_TRAVEL.PARTY par 
         on par.ID = sf.PARTYID 
       WHERE 
        c.PRIMARYSTATUSLID in ('CLAIM_PRIMARY_STATUS:0000000003','CLAIM_PRIMARY_STATUS:0000000001') 
       OR ( c.PRIMARYSTATUSLID = 'CLAIM_PRIMARY_STATUS:0000000004' 
        AND bo.BENEFITOPTIONSTATUSLID in ('BENEFIT_OPTION_STATUS:0000000010', 
                 'BENEFIT_OPTION_STATUS:0000000060', 
                 'BENEFIT_OPTION_STATUS:0000000030') 
        ) 
       group by 
       sf.STAREVENTNUMBER, 
       c.id, 
       c.UPDATEDATE, 
       par.ID) t2 
      on e.ID_EVENEMENT = t2.STAREVENTNUMBER 
     LEFT JOIN 
     (SELECT DISTINCT 
       fact.NUMERO_DOSSIER_STAR, 
       GREATEST(to_date(fact.VSTDTCHG,'yyyymmdd'), 
          to_date(fact.VSTDICHK,'yyyymmdd'), 
          to_date(decode(fact.VSTDIFIN,0,19000101, 
           decode(substr(fact.VSTDIFIN,5), 
           '0230', substr(fact.VSTDIFIN,1,4) 
           || '0301',fact.VSTDIFIN)),'yyyymmdd')) DateRecente, 
       DECODE(virage_cont.id_cont, 
         null,add_months(sysdate,-7*12), 
         add_months(sysdate,-15*12)) dateLimite 
       FROM 
       FACTCAN.XC4DSAV fact 
        LEFT JOIN VIRAGE.CONTRAT virage_cont 
         on fact.VSTNOCNT_VIRAGE = virage_cont.NO_CONTR 
       where 
       fact.NUMERO_DOSSIER_STAR is not null) t3 
      on e.ID_EVENEMENT = t3.NUMERO_DOSSIER_STAR 
    WHERE 
      t1.dateRecente < add_months(sysdate, -7*12) 
     AND t2.dateRecente < add_months(sysdate, -7*12) 
     AND virage_c.id_cont is null 
     AND t2.ID_PERSONNE_UNIVERS is not null 
     AND t1.ID_PERSONNE_STAR is null 
     AND t3.dateRecente < t3.dateLimite 
    FETCH 
     FIRST 1000 ROWS ONLY; 

當我試圖從事件的結果與任何 t1.ID_PERSONNE_STAR或t2.ID_PERSONNE_UNIVERS爲空,查詢不返回任何東西時,它其實應該回報一些數據。儘管如此,這不是無效的工作。任何想法?

+0

使用'left join'時,必須注意濾除where子句中不匹配的記錄。 –

+0

您在條件中使用了'AND' - t2.ID_PERSONNE_UNIVERS不爲空且t1.ID_PERSONNE_STAR爲空。所以如果兩個條件都是正確的,你會得到數據。 –

+0

是的,即使這些條件中的任何一個爲空,也不會返回數據。 – Markasius

回答

0

我更新了查詢的可讀性。另外,正如其他人所指出的,你必須小心WHERE子句。你可能會碰到的問題是,你的where子句中的T1,T2和T3的左聯接...向上移動這些那些加入...恩

,你必須

left join (rest of the left-join subquery with alias) t1 
    on t1.ID_EVENEMENT = E.ID_EVENEMENT 

變化到

on t1.ID_EVENEMENT = E.ID_EVENEMENT 
AND t1.dateRecente < add_months(sysdate, -7*12) 

這樣,日期要求是左加入的一部分。通過在WHERE子句中將其轉換爲INNER JOIN。

您可以將T1「IS NULL」測試留在where子句部分,因爲您顯式地期望沒有匹配的記錄。

檢查其他左連接的類似情況...將CRITERIA移到JOIN/ON子句並從WHERE中移除。 Where子句應該有最終期望值「IS NULL」。