2017-06-21 10 views
0

私はいくつかのテストケースをSQLで構築しようとしています。問題は、一致するIDのないデータを取得しようとしたときにデータが返されないときに、左結合でテーブルに結合しようとしたときです(私の理解が正しい場合は、一致する行と一致しない行の両方を返す必要があります)。ここでは、コードです:SQL結合が正しいデータを返さない

私はどちらか t1.ID_PERSONNE_STARまたはt2.ID_PERSONNE_UNIVERSがnullでイベントから結果を取得しようとしている
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; 

、クエリは、実際の見返りにそれが必要何かを返すされていませんいくつかのデータ。しかし、意図したとおりにnull仕事ではありません。何か案が?

+0

'left join'を使うときは、' where'句で不一致レコードを除外することに注意する必要があります。 –

+0

あなたは 't2.ID_PERSONNE_UNIVERSがヌルでなく、t1.ID_PERSONNE_STARがヌルである 'という条件で' AND'を使用しています。両方の条件が正しい場合は、データを取得します。 –

+0

はいポイントですが、いずれかの条件がnullの場合はデータは返されません。 – Markasius

答えて

0

クエリの可読性を更新しました。また、他の人が触れたように、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) 

このように、日付要件はLEFT-JOINの一部です。これをWHERE句に入れてINNER JOINに変換します。

一致するレコードが明示的に存在しないため、where句部分にT1 "IS NULL"テストを残すことができます。

他の左ジョインと同様の状況を確認してください... CRITERIAをJOIN/ON句に移動し、WHEREから削除してください。 where句は、最終的な期待値として "IS NULL"を持つべきです(SHOULD)。

関連する問題