我正在努力处理具有以下要求的查询:
表A
ID Name Key 1 A1 Key1 2 A2 Key2 3 A3 Key3
表B
ID A_ID NAME CONTAINER_A_ID 1 1 B1 NULL 2 1 B2 NULL 3 1 B3 2 4 2 B4 NULL 5 2 B5 NULL 6 3 B6 NULL 7 3 B7 NULL
表A中的Key列是唯一的
表B中的A_ID列是表A
的外键
表B中的CONTAINER_A_ID列表示表B中的行可以是a 容器,它包含CONTAINER_A_ID值指示的其他数据行。
以下是示例:
输入参数是表A键列值,比如说A.Key ='key1',基于上面的示例数据的结果将是:
A.ID A.NAME A.KEY B.ID B.A_ID B.NAME B.CONTAINER_A_ID 1 A1 KEY1 1 1 B1 NULL 1 A1 KEY1 2 1 B2 NULL 1 A1 KEY1 3 1 B3 2 2 A2 KEY2 4 2 B4 NULL 2 A2 KEY2 5 2 B5 NULL
如果输入参数是A.Key ='key2',则结果为:
A.ID A.NAME A.KEY B.ID B.A_ID B.NAME B.CONTAINER_A_ID 2 A2 KEY2 4 2 B4 NULL 2 A2 KEY2 5 2 B5 NULL
由于
答案 0 :(得分:2)
这是在Oracle 11g上。
如果你是专门寻找CONNECT BY我还没有意识到这一点。
drop table t1; drop table t2;
create table t1 (id int primary key, name char(5), key char(5));
create table t2 (id int primary key, a_id int, name char(5) , container int);
insert into t1 values (1, 'A1', 'K1');
insert into t1 values (2, 'A2', 'K2');
insert into t1 values (3, 'A3', 'K3');
insert into t2 values (1, 1, 'B1', null);
insert into t2 values (2, 1, 'B2', null);
insert into t2 values (3, 1, 'B3', 2);
insert into t2 values (4, 2, 'B4', null);
insert into t2 values (5, 2, 'B5', null);
insert into t2 values (6, 3, 'B6', null);
insert into t2 values (7, 3, 'B7', null);
with t(id, name, key, bid, aid, bname, con) as (
select a.id, a.name, a.key, b.id, b.a_id, b.name, b.container
from t1 a
inner join
t2 b
on a.id = b.a_id
where a.key = 'K1'
union all
select a.id, a.name, a.key, b.id, b.a_id, b.name, b.container
from t t
inner join
t1 a
on a.id = t.con
inner join
t2 b
on a.id = b.a_id
) select * from t;
编辑:回应Jorge的评论
insert into t2 values (4, 2, 'B4', 3);
答案 1 :(得分:2)
with TableA as
(
select 1 id, 'A1' Name, 'Key1' key from dual union all
select 2, 'A2', 'Key2' from dual union all
select 3, 'A3', 'Key3' from dual
)
, tableb as
(
select 1 id, 1 a_id, 'B1' name , null CONTAINER_A_ID from dual union all
select 2 , 1 , 'B2' , null from dual union all
select 3 , 1 , 'B3' , 2 from dual union all
select 4 , 2 , 'B4' , null from dual union all
select 5 , 2 , 'B5' , null from dual union all
select 6 , 3 , 'B6' , null from dual union all
select 7 , 3 , 'B7' , null from dual
)
select
a.id, a.name, a.key, b.id, b.a_id, b.name, b.container_a_id
from
tableb b
left join
tablea a
on
a.id = b.a_id
start with
A.Key = 'Key1'
connect by
prior b.container_a_id = b.a_id;
如果您需要订购,请将order by a.id, b.id,a.name,...;
添加到最后。
答案 2 :(得分:0)
CTE可以在11g Oracle中使用。我刚刚看到Jorge在我面前。如果你只是在CTE中使用tableB然后加入CTE来获取所有字段,就更容易看到递归是如何工作的那样
with
recurse (a_id, b_id, parent_id)
as
(select a_id, id, container_a_id as parent_id
from tableB
WHERE A_ID = 1 -- Put your parameter here
union all
select b.a_id, b.id, b.container_a_id
from recurse r, tableB b
where b.a_id = r.parent_id
)
select r.a_id, a.name, a.key, b.id, b.a_id, b.name, b.container_a_id
from recurse r, tableA a, tableB b
where r.a_id = a.id and r.b_id = b.id
;
这会得到相同的结果,但是虽然您必须使用a_id而不是a_key来表示条件,但理解递归会更容易一些。
所以,请留下这个,以防有人了解CTE。