在介绍层次查询的过程中,我们将会反复使用到下面这棵“树”,虽然它看上去只是一棵很普通的树,但其中蕴含着很多值得探索的内容。
A
/ /
B C
/ /
D E
/ /
F G
1.“树”的自述
A:我是B和C的父亲
B:我是A的儿子,是D的父亲,是C的亲兄弟
C:我是A的儿子,是E的父亲,是B的亲兄弟
D:我是B的儿子,是F和G的父亲
E:我是C的儿子
F:我是D的儿子,是G的亲兄弟
G:我是D的儿子,是F的亲兄弟
2.通过自关联表T构造上述那棵“树”
sec@ora10g> create table t (x varchar2(10),y number,z number);
sec@ora10g> alter table t add constraint pk_t primary key (y);
sec@ora10g> alter table t add constraint fk_t foreign key (z) references t (y);
sec@ora10g> insert into t values ('A',1,null);
sec@ora10g> insert into t values ('B',2,1);
sec@ora10g> insert into t values ('C',3,1);
sec@ora10g> insert into t values ('D',4,2);
sec@ora10g> insert into t values ('E',5,3);
sec@ora10g> insert into t values ('F',6,4);
sec@ora10g> insert into t values ('G',7,4);
sec@ora10g> commit;
3.表T的内容
sec@ora10g> select * from t;
X Y Z
---------- ---------- ----------
A 1
B 2 1
C 3 1
D 4 2
E 5 3
F 6 4
G 7 4
7 rows selected.
仔细将这个表和上面的树做个比对,显然,它们是等价的。
T表体现的是一种层级关系,可以想象z列内容记录的是该行记录的父亲结点信息。
4.使用层次查询“遍历”这棵树。
使用最简单的connect by语句便可完成对整个树的全面遍历,如果您是第一次使用这样的高级SQL语句,请不要晕,因为没有做更多的限制,结果可能貌似有点乱,不过可以静下心来仔细研究一番,便可顿开茅塞。
sec@ora10g> select x, y, z from t connect by prior y=z;
X Y Z
---------- ---------- ----------
B 2 1
D 4 2
F 6 4
G 7 4
C 3 1
E 5 3
D 4 2
F 6 4
G 7 4
E 5 3
F 6 4
G 7 4
A 1
B 2 1
D 4 2
F 6 4
G 7 4
C 3 1
E 5 3
19 rows selected.
5.请按照我标注的颜色,分组查看上面的内容
红色的4行数据(B、D、F、G):表示结点A左侧的整棵子树;
蓝色的2行数据(C、E):表示结点A右侧的整棵子树;
橙色的3行数据(D、F、G):表示结点B左侧的整棵子树;
绿色的E:叶子结点;
棕色的F:叶子结点;
浅蓝的G:叶子结点;
紫色的7行数据(A、B、D、F、G、C、E):表示整棵树。
通过上面的解释,您应该对自关联的表的层次查询有了一个感性的认识。
6.只得到以结点“A”为根的树
也就是只想得到上面紫色的7条数据,因为其他数据对于我来说是一种没有必要的重复。
此时我们仅需要使用层次查询中的start with子句便可。
sec@ora10g> select x, y, z from t start with x = 'A' connect by prior y=z;
X Y Z
---------- ---------- ----------
A 1
B 2 1
D 4 2
F 6 4
G 7 4
C 3 1
E 5 3
7 rows selected.
这里使用“start with x = 'A'”子句可以限制只选取以结点“A”为根的树。
7.小结
使用层次查询可以非常便捷的得到自关联表的内在逻辑联系,这是Oracle的一个特色功能,将繁琐的功能化解到了一条SQL之中。
Good luck.
【层次查询】Hierarchical Queries之“树的遍历”
最新推荐文章于 2024-03-11 20:00:09 发布
转帖自
--http://space.itpub.net/519536/viewspace-623809