如何在不使用经典方式或不使用where子句的情况下解决父子脚本

时间:2019-06-27 09:29:32

标签: sql oracle

我正在寻找可以像父子一样工作的解决方法,但不使用递归搜索。我无法使用临时表。

此脚本可以正常工作,但始终运行600秒。

SELECT CONNECT_BY_ROOT party_id as ANCESTOR, 
       party_id, role_id, subject_id
FROM onecrm.CRM_PARTY 
WHERE LEVEL>1 
and party_id = 'text'
CONNECT BY PRIOR Party_id=parent_id;

这很好用,但是包含3个步骤。由于任务汇总,我只需要使用一个步骤即可。

select internal_id, party_id, parent_id, subject_id, channel_type_id 
from onecrm.O_ORDER oo 
  join onecrm.CRM_PARTY cp on oo.party_ref_no = cp.party_ref_no 
where internal_id = 'O7VYECF';

结果:

INTERNAL_ID, PARTY_ID, PARENT_ID, SUBJECT_ID, CHANNEL_TYPE_ID
O7VYECF     110179237   110179236  null           CRM
select internal_id, cp.party_id, parent_id
from onecrm.O_ORDER oo 
  right join onecrm.CRM_PARTY cp on oo.party_ref_no = cp.party_ref_no 
where cp.party_id = '110179236';

结果:

INTERNAL_ID, PARTY_ID, PARENT_ID
OAMUAY7      110179236  null
select internal_id, cp.party_id, parent_id, cp.subject_id, 
       channel_type_id, full_name, phone_no_1, phone_no_2, email, segment
from onecrm.O_ORDER oo 
  right join onecrm.CRM_PARTY cp on oo.party_ref_no = cp.party_ref_no 
  left join onecrm.CRM_SUBJECT cs on cs.SUBJECT_ID = cp.SUBJECT_ID
  left join onecrm.crm_contact_ref ccr on ccr.conre_ref_no = cs.subj_ref_no
  left join onecrm.CRM_CONTACT_EXT cce on cce.contact_id = ccr.contact_id 
where cp.party_id = '110179236';

预期结果:

INTERNAL_ID, PARTY_ID, PARENT_ID, SUBJECT_ID, CHANNEL_TYPE_ID, FULL_NAME, PHONE_NO_1, PHONE_NO_2, EMAIL, SEGMENT

OAMUAY7   110179236 null    102219217   TGB great_company s.r.o.                
xxx            xxx      TNC     RNC

预期结果是仅写入internal_id并获得parent_id信息

1 个答案:

答案 0 :(得分:1)

原始connect by查询没有start with子句。这意味着它正在为表中的每一行计算树!

然后将where子句应用于生成的树。

例如,以下代码为C1 = 1,C1 = 2和C1 = 3的行构建树起点。

create table t as 
  select level c1, level - 1 c2 
  from   dual
  connect by level <= 3;

select t.*, 
       connect_by_root c1 rt
from   t
connect by prior c1 = c2;

C1    C2    RT   
    1     0     1 
    2     1     1 
    3     2     1 
    2     1     2 
    3     2     2 
    3     2     3 

当您将更多数据加载到表中时,这将非常迅速地降低查询的速度。

即使您的where子句意味着只返回几行,您也很有可能正在处理庞大的数据集。

为避免这种情况,几乎可以肯定需要一个start with子句。这定义了哪一行是树的根:

select t.*, 
       connect_by_root c1 rt
from   t
start  with c1 = 1
connect by prior c1 = c2;

C1    C2    RT   
    1     0     1 
    2     1     1 
    3     2     1