Oracle SQL UNION ALL with NULL在尝试外部联接数据时会导致性能问题
我试图构建一个查询,返回Oracle的客户及其笔记。不幸的是,我从中选择数据的notes表与客户没有任何1-1联接,因此我使用party id并在包含客户合同号的notes中查找特定字符串来联接数据 我想做的是返回客户、合同和他们的注释信息(如果注释存在或不存在) 我知道下面的代码很长,但我特别感兴趣的是如何处理代码的最后一部分(因此我在最后加入notes信息的代码)。我在查询的当前版本中遇到的问题是,如果我通过添加带有null的UNION ALL来加入FORCE_NOTE_GUAR和FORCE_NOTE_CUST子查询,那么性能会非常差 如果我删除该联合,所有性能都很好,但是我只得到有注释的客户,没有没有没有注释的客户 我知道这是一个很长的查询和一个很长的职位,所以请平我,如果我可以提供更多的信息Oracle SQL UNION ALL with NULL在尝试外部联接数据时会导致性能问题,sql,oracle,oracle-ebs,Sql,Oracle,Oracle Ebs,我试图构建一个查询,返回Oracle的客户及其笔记。不幸的是,我从中选择数据的notes表与客户没有任何1-1联接,因此我使用party id并在包含客户合同号的notes中查找特定字符串来联接数据 我想做的是返回客户、合同和他们的注释信息(如果注释存在或不存在) 我知道下面的代码很长,但我特别感兴趣的是如何处理代码的最后一部分(因此我在最后加入notes信息的代码)。我在查询的当前版本中遇到的问题是,如果我通过添加带有null的UNION ALL来加入FORCE_NOTE_GUAR和FORCE
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));
使用
nulls
删除联合
,并将查询更改为左联合
版本:
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||'%'
使用
nulls
删除联合
,并将查询更改为左联合
版本:
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||'%'
我相信你可以(至少)从中删掉很多不相关的栏目,让人们更容易相处?@TonyAndrews好观点。我相信你可以(至少)删掉很多不相关的栏目,让人们更容易相处?@TonyAndrews好观点。是的,这个问题是一个很好的例子,说明了为什么旧的连接语法被弃用而支持ANSI连接。对于外部联接,ANSI样式更易于阅读和理解。谢谢!我最初考虑使用左连接,但与和/或过于复杂了……是的,这个问题是一个很好的例子,说明了为什么旧连接语法被弃用而支持ANSI连接。对于外部联接,ANSI样式更易于阅读和理解。谢谢!我最初考虑使用左连接,但由于和/或。。。