Oracle Hierarchical Queries
我正在努力处理具有以下要求的查询:
表A
1
2 3 4 5 |
ID Name Key
1 A1 Key1 |
表B
1
2 3 4 5 6 7 8 |
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 中的行可以是
容器,它包含由 CONTAINER_A_ID 值指示的其他数据行。
下面是例子:
输入参数为表A键列值,假设A.Key = \\’key1\\’,根据上述样本数据得出的结果为:
1
2 3 4 5 6 |
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\\’,则结果为:
1
2 3 |
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 |
谢谢
- 如果您添加 A.Key = ‘key1’ 作为条件,则将永远不会返回最后两个注册表!那是你真正需要的吗?
- 是的,它是。我将在我的帖子中提供更多示例,以使我的问题更清楚,谢谢。
- 我想我刚刚明白了。过滤器中的注册表和过滤结果中的子项。我想这会有点难。我不会尝试提供答案,因为我这里没有预言机来测试它。使用 CTE 的东西也许应该解决它。
这是用于分层查询
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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 ) |
如果您需要订购,请在末尾添加 order by a.id, b.id,a.name,…;。
这是在 Oracle 11g 上。
如果您专门寻找 CONNECT BY,我还不知道。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
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 t2 values (1, 1, ‘B1’, null); with t(id, name, key, bid, aid, bname, con) as ( |
编辑:回应豪尔赫的评论
1
|
insert into t2 values (4, 2, ‘B4’, 3);
|
- 那会从孩子那里解决孩子吗?我的意思是如果 insert into t2 values (4, 2, ‘B4’, 3); 怎么办?您的查询是否有效?
- @Jorge 我相信确实如此-见上文。如果您发现任何问题,请告诉我。
- 伟大的。 1 给你 :)
CTE 可以在 11g Oracle 中使用。我刚刚看到豪尔赫在我面前。如果您只是在 CTE 中使用 tableB 然后加入 CTE 以获取所有字段,则更容易看到递归是如何工作的,像这样
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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 的知识。
来源:https://www.codenong.com/37364302/