2017-06-21 83 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”。