外部联接不适用于现有查询

时间:2019-09-20 20:26:40

标签: sql oracle

在下面的查询中,我希望所有在pay_dir_cards_f中没有记录的人,因此在相应的pay_dir_card_components_f中没有记录, pay_dir_comp_details_f。

我在下面添加了外部联接,但仍未获得上述所需记录。相反,我得到的是表pay_dir_cards_f中的记录。 如何在以下查询中修改外部联接。

另外,请注意,是的,我确实知道这种连接样式是一种旧样式,我应该改用新的约定,但是我必须更新现有查询,因此不使用它。

SELECT DISTINCT papf.person_number, 
                        PAPF.effective_start_date, 
                        PAPF.effective_end_date ,
                        paam.ASSIGNMENT_NUMBER 
        FROM   per_all_people_f papf, 
               per_all_assignments_m paam, 
               pay_pay_relationships_dn pprd, 
               pay_rel_groups_dn prgd, 
               pay_dir_cards_f pdcf, 
               pay_dir_card_components_f pdccf1, 
               pay_dir_comp_details_f pdcdf1 
        WHERE  SYSDATE BETWEEN papf.effective_start_date AND 
                               papf.effective_end_date 
               AND paam.person_id = papf.person_id 
               AND paam.effective_latest_change = 'Y' 
               AND paam.assignment_type IN ( 'E', 'C' ) 
               AND pprd.person_id = papf.person_id 
               --And PPRD.LEGISLATIVE_DATA_GROUP_ID = PLDGV.LEGISLATIVE_DATA_GROUP_ID  
               AND pprd.payroll_stat_unit_id = paam.legal_entity_id 
               AND prgd.payroll_relationship_id = pprd.payroll_relationship_id 
               AND prgd.assignment_id = paam.assignment_id 
               AND prgd.group_type = 'A' 
               AND pdcf.payroll_relationship_id(+) = 
                   prgd.payroll_relationship_id 
               AND Trunc(SYSDATE) BETWEEN paam.effective_start_date AND 
                                          paam.effective_end_date 
               AND Trunc(SYSDATE) BETWEEN papf.effective_start_date AND 
                                          papf.effective_end_date 
               AND Trunc(SYSDATE) BETWEEN pdcf.effective_start_date AND 
                                          pdcf.effective_end_date 
               AND pdccf1.dir_card_id(+) = pdcf.dir_card_id
               AND pdcdf1.dir_card_comp_id(+) = pdccf1.dir_card_comp_id 

               AND Trunc(SYSDATE) BETWEEN pdcdf1.effective_start_date AND 
                                          pdcdf1.effective_end_date 
               AND pdcdf1.effective_start_date BETWEEN 
                   pdccf1.effective_start_date AND pdccf1.effective_end_date 
        ORDER  BY papf.person_number

1 个答案:

答案 0 :(得分:0)

我了解到您正在OUTER JOIN上使用pay_dir_cards_f,而且并没有如您所愿。

旧式联接和格式错误使查询难以阅读...当扫描查询中与pay_dir_cards_f联接条件有关的部分时,一个条件似乎有问题:

AND Trunc(SYSDATE) BETWEEN pdcf.effective_start_date AND pdcf.effective_end_date 

由于(至少)这种情况,我怀疑Oracle能够执行OUTER JOIN。存在严重的局限性,并且警告再次提示使用旧联接,尤其是OUTER JOIN,例如documented in the 10g manual

我强烈建议您重写查询以使用非古代联接。那可能只会使您的问题消失。

作为善意的标志,请在下面找到重新构建(和重新格式化)查询的第一次尝试。您需要对其进行审查,并可能会解决一些问题,但这应该是一个很好的起点:

SELECT DISTINCT 
    papf.person_number, 
    papf.effective_start_date, 
    papf.effective_end_date ,
    paam.ASSIGNMENT_NUMBER 
FROM   
    per_all_people_f papf 
    INNER JOIN per_all_assignments_m paam
        ON  paam.person_id = papf.person_id 
        AND paam.effective_latest_change = 'Y' 
        AND paam.assignment_type IN ( 'E', 'C' ) 
        AND TRUNC(SYSDATE) BETWEEN paam.effective_start_date AND paam.effective_end_date        
    INNER JOIN pay_pay_relationships_dn pprd
        ON  pprd.person_id = papf.person_id 
        -- AND pprd.legislative_data_group_id = pldgv.legislative_data_group_id  
        AND pprd.payroll_stat_unit_id = paam.legal_entity_id 
    INNER JOIN pay_rel_groups_dn prgd
        ON  prgd.payroll_relationship_id = pprd.payroll_relationship_id 
        AND prgd.assignment_id = paam.assignment_id 
        AND prgd.group_type = 'A' 
    INNER JOIN pay_dir_cards_f pdcf
        ON  pdcf.payroll_relationship_id = prgd.payroll_relationship_id 
        AND TRUNC(SYSDATE) BETWEEN pdcf.effective_start_date AND pdcf.effective_end_date 
    LEFT JOIN pay_dir_card_components_f pdccf1
        ON  pdccf1.dir_card_id = pdcf.dir_card_id
        AND pdccf1.dir_card_id = pdcf.dir_card_id   
    LEFT JOIN pay_dir_comp_details_f pdcdf1 
        ON  TRUNC(SYSDATE) BETWEEN pdcdf1.effective_start_date AND pdcdf1.effective_end_date 
        AND pdcdf1.dir_card_comp_id = pdccf1.dir_card_comp_id 
WHERE  
    SYSDATE BETWEEN papf.effective_start_date AND  papf.effective_end_date 
    AND TRUNC(SYSDATE) BETWEEN papf.effective_start_date AND papf.effective_end_date
ORDER  BY papf.person_number