2017-09-22 6 views
0

Oracleとそのノートから顧客を戻す問合せを作成しようとしています。残念ながら、私がデータを選択しているノートテーブルには顧客との1つのジョインがありませんので、パーティIDを使用してデータに参加し、顧客契約番号を含むノート内の特定の文字列を探しています。Oracle SQL UNION ALLを使用すると、データを外部結合しようとするとパフォーマンスの問題が発生します。

私がしたいことは、メモが存在し、メモが存在しない場合、顧客、契約、およびそのメモ情報を返すことです。

私は以下のコードが長いことを知っていますが、私は特にコードの最後のビットを処理する方法に興味があります(最後にメモ情報と結合するコード)。現在のバージョンのクエリで問題があるのは、FORCE_NOTE_GUARおよびFORCE_NOTE_CUSTサブクエリにUNION ALLにNULLを追加すると、パフォーマンスが非常に悪いことです。

私がそのUNION ALLを削除した場合、パフォーマンスは良好ですが、私はノートしか持っていない顧客を獲得するだけで、ノートを持っていない顧客はいません。

私はそれが長い質問と長い投稿であることを知っていますので、私は詳細を与えることができれば私にpingしてください。

 SELECT QUERY_MAIN.* 
,  FORCE_NOTE_CUST.NOTE_CREATION_DATE          AS FORCE_ACCEPT_DATE_CUST 
,  FORCE_NOTE_GUAR.NOTE_CREATION_DATE          AS FORCE_ACCEPT_DATE_GUAR 
,  FORCE_NOTE_CUST.ENTERED_BY_NAME           AS USER_FORCE_ACCEPT_CUST 
,  FORCE_NOTE_GUAR.ENTERED_BY_NAME           AS USER_FORCE_ACCEPT_GUAR 
,  FORCE_NOTE_CUST.NOTES             AS NOTES_CUST 
,  FORCE_NOTE_GUAR.NOTES             AS NOTES_GUAR 
FROM (SELECT HP.PARTY_ID 
     ,  HCA_CUSTOMER.ACCOUNT_NUMBER          AS ACCOUNT_NUMBER 
     ,  OKH.CONTRACT_NUMBER            AS CONTRACT_NUMBER 
     ,  DECODE(OKP.ATTRIBUTE5, 'F', 'Y', 'N')        AS CUSTOMER_FORCE 
     ,  DECODE(GUAR_FORCE.FORCE_FLAG, 'F', 'Y', 'N')      AS GUARANTOR_FORCE 
     -------------------------------------------------------------------------- 
     FROM ... customer tables) QUERY_MAIN 
-------------------------------------------------------------------------------- 
, (SELECT* FROM(SELECT JII.PARTY_ID            AS PARTY_ID 
       ,  TO_CHAR(DECODE(JIHA.ACTION, 'Converted' 
           , SUBSTR(JNV.NOTES_DETAIL,1,2000) 
           , NVL(JNV.NOTES 
            , SUBSTR(JNV.NOTES_DETAIL 
              , 1 
              , 2000))))       AS NOTES 
       ,  JNV.CREATION_DATE          AS NOTE_CREATION_DATE 
       ,  NVL(PEP.FULL_NAME, FU_INT.USER_NAME)      AS ENTERED_BY_NAME 
       ---------------------------------------------------------------- 
       FROM ... notes tables) 
    WHERE NOTES LIKE '%Guarantor acceptance manually progressed%' 
    UNION ALL 
    SELECT NULL                 AS PARTY_ID 
    ,  NULL                 AS NOTES 
    ,  NULL                 AS NOTE_CREATION_DATE 
    ,  NULL                 AS ENTERED_BY_NAME 
    FROM DUAL)                 FORCE_NOTE_GUAR 
-------------------------------------------------------------------------------- 
, (SELECT* FROM(SELECT JII.PARTY_ID            AS PARTY_ID 
       ,  TO_CHAR(DECODE(JIHA.ACTION, 'Converted' 
           , SUBSTR(JNV.NOTES_DETAIL,1,2000) 
           , NVL(JNV.NOTES 
            , SUBSTR(JNV.NOTES_DETAIL 
              , 1 
              , 2000))))       AS NOTES 
       ,  JNV.CREATION_DATE          AS NOTE_CREATION_DATE 
       ,  NVL(PEP.FULL_NAME, FU_INT.USER_NAME)      AS ENTERED_BY_NAME 
       ---------------------------------------------------------------- 
       FROM ... notes tables) 
    WHERE NOTES LIKE '%Customer acceptance manually progressed%' 
    UNION ALL 
    SELECT NULL                 AS PARTY_ID 
    ,  NULL                 AS NOTES 
    ,  NULL                 AS NOTE_CREATION_DATE 
    ,  NULL                 AS ENTERED_BY_NAME 
    FROM DUAL)                 FORCE_NOTE_CUST 
-------------------------------------------------------------------------------- 
-- Outer logic to select the appropriate notes 
WHERE 1 = 1 
AND ((CUSTOMER_FORCE = 'N' AND FORCE_NOTE_CUST.PARTY_ID IS NULL) 
     --If CUSTOMER_FORCE = 'Y' 
     --If the customer has force accepted, we need to find the note 
     OR ( CUSTOMER_FORCE = 'Y' 
      AND QUERY_MAIN.PARTY_ID    = FORCE_NOTE_CUST.PARTY_ID      
      AND INSTR(FORCE_NOTE_CUST.NOTES, CONTRACT_NUMBER) > 0)) 
AND ((GUARANTOR_FORCE = 'N' AND FORCE_NOTE_GUAR.PARTY_ID IS NULL) 
     --If GUARANTOR_FORCE = 'Y' 
      --If the guarantor has force accepted, we need to find the note 
     OR (GUARANTOR_FORCE = 'Y' 
      AND QUERY_MAIN.PARTY_ID    = FORCE_NOTE_GUAR.PARTY_ID 
      AND INSTR(FORCE_NOTE_GUAR.NOTES, CONTRACT_NUMBER) > 0)); 
+2

と連携? –

+0

@TonyAndrews良い点。 – Ucello

答えて

3

nullsunionsを削除し、left joinバージョンにあなたのクエリを変更する:私はあなたが人々にシンプルな何かを与えることの外に無関係な列(少なくとも)の多くを切ることができると確信している

SELECT QUERY_MAIN.*, 
     FORCE_NOTE_CUST.NOTES, 
     FORCE_NOTE_GUAR.NOTES 
    FROM QUERY_MAIN 
    LEFT JOIN FORCE_NOTE_GUAR on FORCE_NOTE_CUST.PARTY_ID = QUERY_MAIN.PARTY_ID 
          and FORCE_NOTE_CUST.NOTES like '%'||CONTRACT_NUMBER||'%' 
    LEFT JOIN FORCE_NOTE_CUST on FORCE_NOTE_GUAR.PARTY_ID = QUERY_MAIN.PARTY_ID 
          and FORCE_NOTE_GUAR.NOTES like '%'||CONTRACT_NUMBER||'%' 
+0

この質問は、古い結合構文がANSI結合のために推奨されなくなった理由の良い例です。外部結合の場合、ANSIスタイルは読みやすく理解しやすくなります。 – kfinity

+0

ありがとうございます! 私は最初に左の結合を使用すると思ったが、AND/ORで複雑すぎる... – Ucello

関連する問題