2013-08-17 75 views
2

在我工作的当前项目中,遇到了一个特殊情况。请考虑以下表结构:跨多个表的Oracle分层查询

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 s(数据可以跨越多个级别的层次结构)从特定的AGENCY_ID开始。

+0

做了一些研究条款“的连接”。 – OldProgrammer

回答

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  

给你的SQL捣鼓你的榜样http://www.sqlfiddle.com/#!4/3f692/5

+0

非常感谢.....这正是我想要的 – Shovan