Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Oracle SQL中使用外部联接表的模式匹配_Sql_Oracle_Oracle Fusion Apps - Fatal编程技术网

在Oracle SQL中使用外部联接表的模式匹配

在Oracle SQL中使用外部联接表的模式匹配,sql,oracle,oracle-fusion-apps,Sql,Oracle,Oracle Fusion Apps,我正在Oracle Fusion Financials中创建一个数据模型,以将供应商使用和客户使用的各方匹配在一起。这些当事人有一个以其名义登记的代码。 在Google上搜索表名将找到模式(例如),尽管不需要查看模式来解决这个问题 我们的数据质量并不是我们想要的。为了确保我没有丢失记录,我需要加入其他名称中也包含代码的团体 这是我到目前为止得到的结果 SELECT RCTA.TRX_NUMBER ,RCTA.CT_REFERENCE ,HP.PARTY_NAME PARTY_NAME1 ,

我正在Oracle Fusion Financials中创建一个数据模型,以将供应商使用和客户使用的各方匹配在一起。这些当事人有一个以其名义登记的代码。 在Google上搜索表名将找到模式(例如),尽管不需要查看模式来解决这个问题

我们的数据质量并不是我们想要的。为了确保我没有丢失记录,我需要加入其他名称中也包含代码的团体

这是我到目前为止得到的结果

SELECT
 RCTA.TRX_NUMBER
,RCTA.CT_REFERENCE 
,HP.PARTY_NAME  PARTY_NAME1
,HP2.PARTY_NAME PARTY_NAME2
,IEBC.IBAN CUSTOMER_IBAN

FROM
 HZ_PARTIES HP,
 HZ_PARTIES HP2,
 IBY_ACCOUNT_OWNERS IAO,
 IBY_EXT_BANK_ACCOUNTS IEBC,
 RA_CUSTOMER_TRX_ALL RCTA,
 HZ_CUST_ACCOUNTS HCA 

WHERE 1=1
  AND RCTA.BILL_TO_CUSTOMER_ID = HCA.CUST_ACCOUNT_ID (+)
  AND HCA.PARTY_ID = HP.PARTY_ID(+)
  AND REGEXP_SUBSTR(HP.PARTY_NAME,'([0-9]{2}[A-Z]{2}[0-9]{3})') in REGEXP_SUBSTR(HP2.PARTY_NAME,'([0-9]{2}[A-Z]{2}[0-9]{3})') -- Join on code found in party name.  
  AND IAO.ACCOUNT_OWNER_PARTY_ID (+) IN (HP2.PARTY_ID)
  AND IAO.EXT_BANK_ACCOUNT_ID = IEBC.EXT_BANK_ACCOUNT_ID (+)
但是,这将执行内部联接,而不是我需要的外部联接

我尝试了以下方法,这会导致语法错误(缺少括号):

还尝试了这个,这使得查询运行的时间太长。未等待结果,因为它可能不正确:

AND ( REGEXP_SUBSTR(HP.PARTY_NAME,'([0-9]{2}[A-Z]{2}[0-9]{3})') = REGEXP_SUBSTR(HP2.PARTY_NAME,'([0-9]{2}[A-Z]{2}[0-9]{3})') (+) -- Join on investor code found in party name.  
   OR NOT REGEXP_LIKE(HP.PARTY_NAME,'([0-9]{2}[A-Z]{2}[0-9]{3})') -- Escape to outer join in case there's no investor code in name
  )

如果有必要,我愿意将(+)连接重写为常规的外部连接语法。

您将外部连接运算符
(+)
放错了位置。应该是这样的:

SQL> with
  2  hp (party_name) as
  3    (select '11AA111' from dual union all
  4     select '22BB222' from dual
  5    ),
  6  hp2 (party_name) as
  7    (select '11AA111' from dual union all
  8     select '33CC333' from dual
  9    )
 10  select hp.*
 11  from hp, hp2
 12  where regexp_substr(hp.party_name     , '([0-9]{2}[A-Z]{2}[0-9]{3})') =
 13        regexp_substr(hp2.party_name (+), '([0-9]{2}[A-Z]{2}[0-9]{3})')
 14  /                                  ---
                                        here
PARTY_N
-------
11AA111
22BB222

SQL>

到适当的时候。。。嗯,是的,如果你愿意,你可以重写它,但我认为在这种情况下它不会有帮助。如果查询按原样运行正常,我会保持原样,并在必要时重写它。

我建议您在
hz\u表中添加一个虚拟列,并对其进行索引,前提是允许您:

alter table hz_parties add code varchar2(7) as regexp_substr(party_name, '([0-9]{2}[A-Z]{2}[0-9]{3})');
create index idx_parties_code on hz_parties (code);
如果不允许更改该表,请改用函数索引:

create index idx_parties_code on hz_parties (regexp_substr(party_name, '([0-9]{2}[A-Z]{2}[0-9]{3})'));
如果不允许在现有表上添加索引,请使用索引创建新表,例如:

create table party_code
(
  party_id  number(10)   not null,
  code      varchar2(7)  not null,
  primary key (party_id)
);

insert into party_code (party_id, code)
select party_id, regexp_substr(party_name, '([0-9]{2}[A-Z]{2}[0-9]{3})')
from hz_parties;

create index idx_party_code on party_code (code, party_id);
在任何一种情况下,您都需要预先提取代码,并且连接应该是快速的

为了找到重复项,只需按代码分组即可。例如:

select code, listagg(party_id, ', ') within group (order by party_id)
from party_code
group by code
having count(*) > 1;

重新编写您的查询以使用显式连接以使其可读,修复错误的外部连接并发现可能的其他错误。

非常感谢您快速回答Littlefoot。我曾试图查找文档中关于将其放置在何处的内容,但我从未发现任何提及此语法的内容。无论如何,我都会使用显式连接重新编写查询。这并不难做到,最终得到的是一个可读的查询。你甚至可以通过这样做发现错误。顺便说一下,你在
中的
子句令我惊讶。它应该类似于(a,b,c)
中的
,但在REGEXP\u SUBSTR中有
(没有括号,只有一个值可比较)和(HP2.PARTY\u ID)
(只有一个值可比较,即
=HP2.PARTY\u ID
)。第一个表达式中缺少括号将导致语法错误异常。
select code, listagg(party_id, ', ') within group (order by party_id)
from party_code
group by code
having count(*) > 1;