Sql 在层次结构查询中显示父对象上的子值

Sql 在层次结构查询中显示父对象上的子值,sql,oracle,hierarchical-data,Sql,Oracle,Hierarchical Data,我有3个表Accountsid、name、parent、CostCentersid、name、parent和AccountPerCostCenteraccount、CostCenter前两个是层次表,最后一个是我用来链接它们的表 下面是一些示例和数据,让我的问题更容易理解 Create table Accounts(id number, name varchar2(100), parent_id number); insert into Accounts Select 1, 'ACTIVE',

我有3个表Accountsid、name、parent、CostCentersid、name、parent和AccountPerCostCenteraccount、CostCenter前两个是层次表,最后一个是我用来链接它们的表

下面是一些示例和数据,让我的问题更容易理解

Create table Accounts(id number, name varchar2(100), parent_id number);
insert into Accounts
Select 1, 'ACTIVE', null from dual union all
Select 11, 'CURRENT ASSETS', 1 from dual union all
Select 111, 'CASH AND CASH EQUIVALENTS', 11 from dual union all
Select 112, 'GENERAL BOX', 11 from dual union all
Select 12, 'GENERAL BOX', 1 from dual union all
Select 121, 'PETTY CASH', 12 from dual union all
Select 122, 'CASH IN BANKS', 12 from dual union all
Select 13, 'BANKS ACCOUNTS', 1 from dual union all
Select 131, 'CENTRAL BANK OF AMERICA', 13 from dual union all
Select 132, 'BANK PROMERICA', 13 from dual union all
select 133, 'BANK DAVIVIENDA', 13 from dual union all
select 1331, 'BANK SCOTIABANK', 133 from dual union all
select 1332, 'BANK PROMERICA EXEMPT', 133 from dual;

create table CostCenters (id number, name varchar2 (100), parent_id number);
insert into CostCenters
select 1, 'Cash flow from operating activities', null from dual union all
select 2, 'Adjustments to reconcile net (loss) to net cash (used)', 1 from dual union all
select 3, 'Provided by operations', 1 from dual union all
select 4, 'Depreciation', 3 from dual union all
select 5, 'Capital Increase Capitalization Accounts Payable to Shareholders', 3 from dual union all
select 6, 'Changes in Assets and Liabilities of the effects of Operation', null from dual union all
select 7, '(Increase) in Accounts Receivable', 6 from dual union all
select 8, 'Decrease in receivables related parties', 6 from dual;


create table AccountsPerCostCenters (account number, CostCenter number);
insert into AccountsPerCostCenters
select 112,2 from dual union all
select 133,4 from dual;

alter table accounts add constraint accounts_pk primary key (id);
alter table costcenters add constraint costcenters_pk primary key (id);
alter table accountspercostcenters add constraint accountspercostcenters_pk primary key (account, costcenter);

alter table accounts add constraint accounts_fk foreign key (parent_id)references accounts (id);
alter table costcenters add constraint costcenters_fk foreign key (parent_id)references costcenters (id);
alter table accountspercostcenters add constraint apcc_accounts_fk foreign key (account)references accounts (id);
alter table accountspercostcenters add constraint apcc_costcenters_fk foreign key (costcenter)references costcenters (id);
正如您所看到的,并非所有帐户都是指向成本中心的链接,并且该链接可以位于树的任何级别。所以我想得到的是每个成本中心的完整账户树,我用

select id, name, level  from accounts acc
connect by prior acc.id=acc.parent_id
start with acc.parent_id is null

id      name                        level
---------------------------------------------
1       ACTIVE                      1
11      CURRENT ASSETS              2
111     CASH AND CASH EQUIVALENTS   3
112     GENERAL BOX                 3
12      GENERAL BOX                 2
121     PETTY CASH                  3
122     CASH IN BANKS               3
13      BANKS ACCOUNTS              2
131     CENTRAL BANK OF AMERICA     3
132     BANK PROMERICA              3
133     BANK DAVIVIENDA             3
1331    BANK SCOTIABANK             4
1332    BANK PROMERICA EXEMPT       4
我想得到的是这样的东西

Id      Name                        Level    Cost Center
--------------------------------------------------------
1       ACTIVE                      1        112
11      CURRENT ASSETS              2        112
111     CASH AND CASH EQUIVALENTS   3        112
112     GENERAL BOX                 3        112
1       ACTIVE                      1        133
13      BANKS ACCOUNTS              2        133
133     BANK DAVIVIENDA             3        133
1331    BANK SCOTIABANK             4        133
1332    BANK PROMERICA EXEMPT       4        133
我知道我必须与AccountsPerCostCenter进行联接才能获得最后一列,但我不知道如何在所有行中获得它,并获得每个成本中心的完整帐户树我尝试了这个

Select acc.id, acc.name, level, apcc.costcenter
From accounts acc
    left join accountspercostcenters apcc on acc.id=apcc.account
connect by prior acc.id=acc.parent_id
start with acc.parent_id is null
但是我找的东西我都找不到

编辑。。 将键添加到表中

对不起,我在结果中犯了一个错误,我只需要完整的树 实际上链接到成本中心的科目并不是每个成本中心的所有科目,因此交叉连接给了我比我需要的行更多的行,再次为没有以正确的方式解释我自己感到抱歉


我使用的是oracle 11g r2,它提供了您描述的输出:

SELECT *
FROM   (
        select acc.id,
               acc.name,
               level AS depth
        from   accounts acc
        connect by prior acc.id=acc.parent_id
        start with acc.parent_id is null
       )
       CROSS JOIN
       AccountsPerCostCenters apcc;

不确定交叉连接是否是您想要的,或者是否有更好的方法链接这两个表?您的DDL中没有包含任何外键,也没有明显的自然连接。

似乎对于每个帐户,您都需要找到其父母、祖父母、子女、孙子孙女等。此查询执行以下操作:

with apcc as (select distinct account id from AccountsPerCostCenters),
a as (
  select id, name, decode(level, 1, 1, -level) l, connect_by_root(id) root
    from accounts 
    connect by prior parent_id = id
    start with id in (select id from apcc)
  union
  select id, name, level l, connect_by_root(id) root
    from accounts 
    connect by parent_id = prior id
    start with id in (select id from apcc) )
select id, name, 
    rank() over (partition by root order by l) lvl, root cost_center
  from a order by root, l
请注意,结果不包含id=111的行。它既不是112的子对象,也不是112的父对象,我怀疑这是手工生成的输出中的错误。 没有显示此行的逻辑原因


在SQL中,我们从apcc的某个点帐户开始,并以两种方式构建两个分层子查询。下一步我们把他们联合起来。最后一个查询对级别进行排序和枚举。

感谢您的回答这正是我想做的,但我不知道如何再次进行thx。是的,当我试图生成我想要的数据示例时,id为111的行是一个错误。我对这个问题考虑得更多了,我认为倒数第二行中,您可能希望使用,而不是-请使用一个适合您的行。