SQL多条件CTE递归

blu*_*ega 11 sql recursion plsql recursive-query common-table-expression

我在数据库中有每个标识符的以下2条信息.控制它们的公司,以及控制它们的公司.

沿线的东西,2个表(忽略一些唯一标识符):

组织

orgid | org_immediate_parent_orgid
1     | 2
2     | 2
3     | 1
5     | 4
Run Code Online (Sandbox Code Playgroud)

关系orgid - > org_immediate_parent_orgid意味着公司有父母.在我看来它只有相关的org_immediate_parent_orgid - > orgid公司的母公司作为子公司

org_affiliations

orgid | affiliated_orgid
2     | 3
2     | 5
4     | 1
1     | 5
Run Code Online (Sandbox Code Playgroud)

orgid - > affiliated_orgid是公司的附属机构

视觉表示应该是这样的:

数据库表示

关于组织的红色关系,蓝色关系org_affiliations.

如果想让2所有的所有公司(或2的子公司)拥有它们的一部分:

select m.org_immediate_parent_orgid
,m.orgid
from oa.organizations m
where m.org_immediate_parent_orgid is not null
start with m.orgid in (Identifiers)
connect by nocycle prior  m.orgid=m.org_immediate_parent_orgid
Run Code Online (Sandbox Code Playgroud)

回报

org_immediate_parent_orgid| orgid
1                         | 2
2                         | 2
3                         | 1
Run Code Online (Sandbox Code Playgroud)

如果想要让所有公司都是2(或2的附属儿子)在其中有一部分:

select aff.orgid,aff.affiliated_orgid
from oa.org_affiliations aff
where aff.affiliated_orgid is not null
start with aff.orgid in(Identifiers)
connect by nocycle prior  aff.affiliated_orgid =aff.orgid
Run Code Online (Sandbox Code Playgroud)

回报

orgid | affiliated_orgid
2     | 3
2     | 5
Run Code Online (Sandbox Code Playgroud)

在所有可能的关系中:

  • Aff - > Aff
  • Aff - > Sub
  • 子 - > Aff
  • 子 - >子

我只找到Sub - > Sub(子公司的子公司),关系(2 - > 1和关系1 - > 3)和Aff - > Aff,关系(2 - > 3和关系2 - > 5 ).它还需要我2个单独的查询.

如何在一个递归查询中提取所有可能的关系?

如果我通过标识符2,则应该可以返回以下内容:

Relation | Loop| orgid | children
Sub      | 1   | 2     |2
Sub      | 1   | 2     |1
Aff      | 1   | 2     |3
Aff      | 1   | 2     |5
Sub      | 2   | 1     |3
Aff      | 2   | 1     |5
Run Code Online (Sandbox Code Playgroud)

在每个周期中,将检查每个标识符的子和附属物.重复为新的孩子.

有关如何接近它的任何想法?

TL:DR: 2个表(子公司\附属公司),2个查询.想要从公司找到所有子公司和附属公司以及所有可能的子公司组合的单一查询.最终预期结果显示,只需按照图片表示.

编辑:正如克雷格评论的那样,我修正了输出.

编辑2:继好帮助克雷格和鲍勃贾维斯给我继续遇到问题.

对于收集子公司,以下代码完美无瑕,输出如我所愿:

with
relations as
(
select orgid as children,org_immediate_parent_orgid as orgid,'Sub' as relation
from oa.organizations 
)
select distinct relation, level, orgid, children
from relations
where children is not null
start with orgid in (identifier)
connect by
nocycle prior children = orgid
order by 2,3,4
Run Code Online (Sandbox Code Playgroud)

AFF也是如此:

with
relations as
(
select affiliated_orgid as children, orgid as orgid,'Aff' as relation
from oa.org_affiliations    
)
select distinct relation, level, orgid, children
from relations
where children is not null
start with orgid in (identifier)
connect by
nocycle prior children = orgid
order by 2,3,4
Run Code Online (Sandbox Code Playgroud)

但不能"联合所有"?

with
relations as
(
select orgid as children,org_immediate_parent_orgid as orgid,'Sub' as relation
from oa.organizations

UNION ALL

select affiliated_orgid as children, orgid as orgid,'Aff' as relation
from oa.org_affiliations    
)
select distinct relation, level, orgid, children
from relations
where children is not null
start with orgid in (identifier)
connect by
nocycle prior children = orgid
order by 2,3,4
Run Code Online (Sandbox Code Playgroud)

在sql开发人员中,我去检查"解释计划和成本从每次跳跃从7到400k,只需添加"union all".任何workarround?CTE内部的问题,在联合alL?

Bob Jarvis解决方案不适用于我有comp-sub-sub-aff的情况,或者它找到公司的所有子公司或所有附属公司

Bob*_*ica 1

这是一个开始:

select 'SUB -> SUB' AS TYPE,
       m.orgid AS ORGID,
       m.org_immediate_parent_orgid AS PARENT_OR_AFF
  from organizations m
  where m.org_immediate_parent_orgid is not NULL
  start with m.orgid in (2)
  connect by nocycle prior m.orgid = m.org_immediate_parent_orgid
UNION ALL
select 'AFF -> AFF' AS TYPE,
       aff.orgid AS ORGID,
       aff.affiliated_orgid AS PARENT_OR_AFF
  from org_affiliations aff
  where aff.affiliated_orgid is not NULL
  start with aff.orgid IN (2)
  connect by nocycle prior aff.affiliated_orgid = aff.orgid;
Run Code Online (Sandbox Code Playgroud)

如果您添加子查询来获取剩余的关系,那么您应该可以开始了。

分享并享受。