Oracle分层查询跨越多个表

时间:2013-08-17 08:20:05

标签: sql oracle hierarchical-query

在我工作的当前项目中,我遇到了一种奇怪的情况。请考虑以下表格结构:

AGY_AGENCY (
  AGENCY_ID       NUMBER(9) not null,
  AGENCY_CD       VARCHAR2(30) not null,
  AGC_LEG_CD      VARCHAR2(30) not null,
  ........................
)

AGY_RELN (
  AGY_RELN_ID            NUMBER(9) not null,
  AGENCY_ID              NUMBER(9) not null,   -- Refers to AGY_AGENCY.AGENCY_ID
  RELATIONSHIP_LINK_TYPE VARCHAR2(30) not null,
  ............................
)

AGY_REL_AGENCY (
  REL_AGY_ID        NUMBER(9) not null,
  AGY_RELN_ID       NUMBER(9) not null, -- Refers to AGY_RELN.AGY_RELN_ID
  RELN_AGENCY_ID    NUMBER(9) not null, -- Refers to AGY_AGENCY.ACY_AGENCY_ID
  ...............................
)

以下是示例数据

AGY_AGENCY 

AGENCY_ID  AGENCY_CD  AGC_LEG_CD
--------------------------
1000,      'ABC',    'ABC'
1001,      'DEF',    'DEF'

AGY_RELN 

AGY_RELN_ID  AGENCY_ID   RELATIONSHIP_LINK_TYPE
----------------------------------------------- 
2000,        1000,       'PARENT_OUTLET'

AGY_REL_AGENCY 

REL_AGY_ID   AGY_RELN_ID    RELN_AGENCY_ID
--------------------------------------------
3000,        2000,          1001

根据这些数据,代理商“DEF”是“ABC”的母公司代理商。

我需要制定一个sql查询,它将返回所有父母,祖父母。从特定AGENCY_ID开始,AGENCY_ID(数据可以跨越多个层次结构)。

1 个答案:

答案 0 :(得分:0)

编辑:对不起,以为ABC是DEF的父母,但是再次检查并看到你说,DEF是ABC的父母,所以我相应地改变了我的答案

这个表结构有点奇怪,两个表就足够了。但别介意。

对包含对自身的引用的表执行分层查询。所以,你需要的是连接这些表来获得单个结果集并通过分层查询执行连接。

考虑到您正在寻找特定记录的父母。说这是agency_cd ='ABC'这就是你要得到它的方式。

select agency_id, agency_cd, level from (
 --Below query will join three tables to get a record and its parent id side-by-side in a row    
 SELECT ag.*, rlag.reln_agency_id AS parent_agency_id 
        FROM agy_agency ag, agy_reln rl, agy_rel_agency rlag  
         WHERE ag.agency_id = rl.agency_id (+)
           AND  rlag.agy_reln_id(+) = rl.agy_reln_id    
) t
where agency_cd <> 'ABC' --discard the record you are looking for itself
connect by agency_id =  prior parent_agency_id -- Connect by is executed before where clause, don't worry about where clause
 start with agency_cd = 'ABC';

另一方面。如果你希望看到整个表格。请尝试以下查询。

 select agency_id, agency_cd, prior agency_id as parent_agency_id, prior agency_cd      as parent_agency_cd, level from (
     SELECT ag.*, rlag.reln_agency_id AS parent_agency_id 
       FROM agy_agency ag, agy_reln rl, agy_rel_agency rlag  
         WHERE ag.agency_id = rl.agency_id (+)
          AND  rlag.agy_reln_id(+) = rl.agy_reln_id
 ) t
 connect by prior agency_id =  parent_agency_id 
 start with parent_agency_id is null    

在这里,您的示例http://www.sqlfiddle.com/#!4/3f692/5

的sql小提琴