消除外部联接上的重复行

时间:2012-11-14 18:51:46

标签: sql oracle left-join duplicate-removal

我正在对我们的Oracle数据库运行查询。

目标是返回以下列 -

  1. 文档ID
  2. 文件创建日期
  3. 组织代码
  4. 文档状态
  5. 总金额
  6. 我遇到的问题是组织代码。 可以使文档ID具有多个组织代码。 我只想要一个实例 - 我不关心其余的(如果存在的话)

    以下是我目前的情况 -

        SELECT * FROM (SELECT DISTINCT (K_HDR.DOC_HDR_ID), 
            K_HDR.CRTE_DT, 
            FS_EXT.VAL AS ORG_CODE,
            REQ.REQS_STAT_CD,
            FS_DOC.FDOC_TOTAL_AMT
        FROM PUR_REQS_T REQ, 
            KREW_DOC_HDR_T K_HDR, 
            FS_DOC_HEADER_T FS_DOC,
            KREW_DOC_HDR_EXT_T FS_EXT
        WHERE REQ.FDOC_NBR = K_HDR.DOC_HDR_ID AND
            FS_DOC.FDOC_NBR = REQ.FDOC_NBR AND
            REQ.FDOC_NBR = FS_EXT.DOC_HDR_ID(+) AND
            FS_EXT.KEY_CD(+)= 'organizationCode' AND
            (K_HDR.CRTE_DT BETWEEN TO_DATE('2011-10-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') 
            AND 
             TO_DATE('2012-09-30 23:59:59', 'YYYY-MM-DD HH24:MI:SS')))
        FINAL_SEARCH ORDER BY FINAL_SEARCH.CRTE_DT;
    

    以下查询返回14,933行。 我应该获得的正确行数是14,789。

    罪魁祸首是组织准则。 例如,当我查看结果集时,我会看到以下内容 -

     DOC_ID   CRTE_DT      ORG_CD    STAT    TOTAL
     .
     .
     .
     496256    5-OCT-11     0        CLOS    2779.89
     496258    5-OCT-11     8050     CLOS    1737.5
     496258    5-OCT-11     8000     CLOS    1737.5
     .
     .
     .
    

    如何摆脱生活在FS_EXT表中的恼人的第二个496258实例? (显然我需要摆脱相同类型的重复值的其他实例)

2 个答案:

答案 0 :(得分:1)

您可以使用SELECTGROUP BY包裹起来,仅使用MIN组织代码。

答案 1 :(得分:1)

所以 - 我最终使用FS_EXT表中的另一列来进一步过滤到组织代码的第一个实例。

如果我查看过滤的列仅显示Document Id = 496258的条目,那么FS_EXT表就是这样的内容。
(请注意,任何给定的文档ID都可能有不同的行数)

 DOC_HDR_EXT_ID     DOC_HDR_ID     KEY_CD                      VAL
 13318096           496258         documentDescription         misc items
 13318098           496258         organizationDocNumber       (null)
 13318099           496258         statusDescription           Closed
 13318101           496258         chartAndOrgCodeForResult    KS-1234
 13318102           496258         vendorName                  APPLE COMPUTERS
 13318103
 .
 .
 .
 .
 .
 13318115           496258         organizationCode            8000
 13318116
 .
 .
 .
 1338118            496258         organizationCode            8050

这是我的新查询,它绕过了使用JOIN OPERATION。

请注意,我使用的是SUBQUERY。要获取OrganizationCode的第一个实例,我在DOC_HDR_EXT_ID列上使用MIN运算符,然后使用该ID检索organizationCode VAL并将其传递回主QUERY。

    SELECT * FROM ( SELECT DISTINCT (K_HDR.DOC_HDR_ID), 
         K_HDR.CRTE_DT, 
         (SELECT KS_EXT.VAL AS ORG_CODE 
              FROM KREW_DOC_HDR_EXT_T KS_EXT 
              WHERE KS_EXT.DOC_HDR_EXT_ID =(
              SELECT MIN(DOC_HDR_EXT_ID) 
              FROM KREW_DOC_HDR_EXT_T FS_EXT_INNER
              WHERE FS_EXT_INNER.DOC_HDR_ID = K_HDR.DOC_HDR_ID 
              AND FS_EXT_INNER.KEY_CD = 'organizationCode')) AS ORG_CODE,
         REQ.REQS_STAT_CD,
         FS_DOC.FDOC_TOTAL_AMT
         FROM PUR_REQS_T REQ, 
         KREW_DOC_HDR_T K_HDR, 
         FS_DOC_HEADER_T FS_DOC,
         KREW_DOC_HDR_EXT_T FS_EXT
         WHERE REQ.FDOC_NBR = K_HDR.DOC_HDR_ID AND
               FS_DOC.FDOC_NBR = REQ.FDOC_NBR AND
               REQ.FDOC_NBR = FS_EXT.DOC_HDR_ID(+) AND
               FS_EXT.KEY_CD(+)= 'organizationCode' AND
               (K_HDR.CRTE_DT BETWEEN TO_DATE('2011-10-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE('2012-09-30 23:59:59', 'YYYY-MM-DD HH24:MI:SS')))
     FINAL_SEARCH ORDER BY FINAL_SEARCH.CRTE_DT;

感谢您的推荐@Alex Poole和@StileCrisis。 你让我对我解决这个问题的方法有不同的看法,我的解决方案整合了你的两个建议。来自Stiles的MIN接近并按Alex Poole过滤另一列。