SQL连接不返回正确的数据

时间:2017-06-21 15:07:57

标签: sql oracle join

我试图在SQL中构建一些测试用例。问题是当我尝试使用左连接加入某个表时(如果我的理解是正确的,则应返回匹配和不匹配的行)当我尝试获取没有匹配ID的数据时,不会返回任何数据。这是代码:

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为空,当查询实际上应返回某些数据时,查询不返回任何内容。但是,这不是预期的工作。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我更新了查询的可读性。另外,正如其他人所指出的,您必须小心WHERE子句。您可能遇到的问题是左边连接的T1,T2和T3的where子句...将这些子句移动到这些连接... ex

你有

的地方
   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”。