0

Oracle データベースに対してクエリを実行しています。

目標は、次の列を返すことです-

  1. ドキュメント ID
  2. ドキュメント作成日
  3. 組織コード
  4. ドキュメントのステータス
  5. 合計金額

私が直面している問題は、組織コードにあります。複数の組織コードを持つドキュメント ID を持つことができます。必要なインスタンスは 1 つだけです - 残りは気にしません (存在する場合)

これが私が現在持っているものです-

    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 番目のインスタンスを取り除くにはどうすればよいですか? (明らかに、同じタイプの重複値の他のインスタンスを取り除く必要があります)

4

2 に答える 2

1

組織コードのみを取得するためにSELECTa を使用して、全体をもう 1 つラップすることができます。GROUP BYMIN

于 2012-11-14T18:56:57.733 に答える
1

そのため、FS_EXT テーブルの別の列を使用して、Org Code の最初のインスタンスにさらに絞り込みました。

ドキュメント 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

そして、これがTHE 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 と @StilesCrisis を推薦してくれてありがとう。あなたは、この問題に対する私のアプローチについて別の考え方をさせてくれました。私の解決策は、あなたの両方の提案を統合しています。Stiles からの MIN アプローチと、Alex Poole ごとの別の列のフィルタリング。

于 2012-11-14T22:41:05.260 に答える