0

我正在尝试构建一个从 Oracle 及其注释返回客户的查询。不幸的是,我从中选择数据的注释表没有与客户的任何 1-1 联接,因此我通过使用当事方 ID 并在包含客户合同编号的注释中查找特定字符串来联接数据。

我想要做的是返回客户,合同和他们的笔记信息,如果笔记存在,如果笔记不存在。

我知道下面的代码很长,但我对如何处理代码的最后一点特别感兴趣(所以我在最后加入注释信息的代码)。我在当前版本的查询中遇到的问题是,如果我通过添加带有空值的 UNION ALL 来加入 FORCE_NOTE_GUAR 和 FORCE_NOTE_CUST 子查询,则性能非常非常糟糕。

如果我删除那个 UNION ALL,性能很好,但是我只得到有笔记的客户,而我没有没有没有笔记的客户。

我知道这是一个很长的查询和一个很长的帖子,所以如果我能提供更多信息,请联系我。

     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));
4

1 回答 1

3

删除unions并将nulls您的查询更改为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||'%'
于 2017-09-22T13:06:31.900 回答