您的位置:首页 > 数据库 > Oracle

Oracle的递归查询

2015-12-06 23:54 561 查看
在有时候设计数据库的时候,数据之间的关系是树型结构的,什么是树型结构呢?比方说:

中国有很多省份,而每个省份又包含了很多市,市里又包括县,县又包括乡或者镇,镇又包括很多村。那么要把这些数据放到一张表里怎么做呢?看看这些数据,是不是很像一颗树呢?有父节点也有子节点。所以我们就可以用id,parentid来表示,比如说中国的id是1,因为在往上的话就没有其父节点了,所以parentid可以是0,那么河北省的id就可以是2,parentid就是1。即河北省的父节点是中国。

在网上找了一段树型结构的数据,建好表后可以直接插入数据库

INSERT INTO SC_DISTRICT(ID,NAME) VALUES(1,'四川省');

INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(2,1,'巴中市');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(3,1,'达州市');

INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(4,2,'巴州区');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(5,2,'通江县');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(6,2,'平昌县');

INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(7,3,'通川区');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(8,3,'宣汉县');

INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(9,8,'塔河乡');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(10,8,'三河乡');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(11,8,'胡家镇');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(12,8,'南坝镇');

INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(13,6,'大寨乡');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(14,6,'响滩镇');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(15,6,'龙岗镇');
INSERT INTO SC_DISTRICT(ID,PARENT_ID,NAME) VALUES(16,6,'白衣镇');

 

在Oracle中,可以在select 命令中使用connect by 子句查询表中的树型结构关系。命令格式如下:

CONNECT BY {PRIOR 列名1=列名2|列名1=PRIOR 裂名2}

[START WITH];

Connect By子句说明每行数据将是按层次顺序检索,并规定将表中的数据连如树型结构的关系中。Prior运算符必须放置在链接关系的两列中某一个的前面,对于节点间父子关系,Prior运算符的一侧表示父节点,在另一侧表示子节点,从而确定查找树结构是顺序是自顶向下还是自底向上;Start With子句用来标识哪个节点作为查找树型结构的根节点。

下面来个简单的应用:查询四川省下面的所有地区

select t.id,t.parent_id,t.name from sc_district t connect by prior t.id=t.prent_id start with id='1'

start with既可以放在connect by 子句的前面,也可以放在connect by子句的后面,所以上面的语句等同于下面的语句

select t.id,t.parent_id,t.name from sc_district t  start with id='1' connect by prior t.id=t.perent_id</span>


查询结果如下:



运算符prior被放置于等号前后的位置,决定着查询时的顺序。

如果prior放在connect by子句中等号的前面时,则从根节点和叶节点的检索,即自顶向下的查询方式。如果prior放在connect by 子句中等号的后面时,则是自底向下的检索。比如,上面的sql语句改为这样就变成了查询塔河乡的所有父节点了。

select t.id,t.parent_id,t.name from sc_district  t  start with id='9' connect by t.id= prior t.perent_id

查询结果如下:



这样看树的层次结构,如果树的层次很多的话看起来就很容易搞混,所以Oracle提供了一个sys_connect_by_path()函数来帮助我们解决这个问题。

         Sys_connect_by_path()函数必须与connect by子句一起使用,参数格式是

sys_connect_by_path(columnName,seperator),其中columnName为要显示的字段,而seperator则为连接各个层次的分隔符。

下面我们来展示一下效果:

select t.id,t.parent_id,t.name,sys_connect_by_path(t.name,'>') from sc_district  t start with t.id='1' connect by prior p.id=p.parent_id



一开始感觉这个递归查询不是很好理解,但是动手去敲,敲了几遍以后就感觉慢慢的懂了。所以,还是要动手去做。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  递归 oracle 数据库