Oracle的递归查询
2015-12-06 23:54
561 查看
在有时候设计数据库的时候,数据之间的关系是树型结构的,什么是树型结构呢?比方说:
中国有很多省份,而每个省份又包含了很多市,市里又包括县,县又包括乡或者镇,镇又包括很多村。那么要把这些数据放到一张表里怎么做呢?看看这些数据,是不是很像一颗树呢?有父节点也有子节点。所以我们就可以用id,parentid来表示,比如说中国的id是1,因为在往上的话就没有其父节点了,所以parentid可以是0,那么河北省的id就可以是2,parentid就是1。即河北省的父节点是中国。
在网上找了一段树型结构的数据,建好表后可以直接插入数据库
在Oracle中,可以在select 命令中使用connect by 子句查询表中的树型结构关系。命令格式如下:
CONNECT BY {PRIOR 列名1=列名2|列名1=PRIOR 裂名2}
[START WITH];
Connect By子句说明每行数据将是按层次顺序检索,并规定将表中的数据连如树型结构的关系中。Prior运算符必须放置在链接关系的两列中某一个的前面,对于节点间父子关系,Prior运算符的一侧表示父节点,在另一侧表示子节点,从而确定查找树结构是顺序是自顶向下还是自底向上;Start With子句用来标识哪个节点作为查找树型结构的根节点。
下面来个简单的应用:查询四川省下面的所有地区
start with既可以放在connect by 子句的前面,也可以放在connect by子句的后面,所以上面的语句等同于下面的语句
查询结果如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202008/10/84fa87ad3dfef47040a31f0c316f07b6)
运算符prior被放置于等号前后的位置,决定着查询时的顺序。
如果prior放在connect by子句中等号的前面时,则从根节点和叶节点的检索,即自顶向下的查询方式。如果prior放在connect by 子句中等号的后面时,则是自底向下的检索。比如,上面的sql语句改为这样就变成了查询塔河乡的所有父节点了。
查询结果如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202008/10/08a4182333938503e908846fbdfc8a88)
这样看树的层次结构,如果树的层次很多的话看起来就很容易搞混,所以Oracle提供了一个sys_connect_by_path()函数来帮助我们解决这个问题。
Sys_connect_by_path()函数必须与connect by子句一起使用,参数格式是
sys_connect_by_path(columnName,seperator),其中columnName为要显示的字段,而seperator则为连接各个层次的分隔符。
下面我们来展示一下效果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202008/10/6ce0afe5f09f4fb4fc5a65418a10a559)
一开始感觉这个递归查询不是很好理解,但是动手去敲,敲了几遍以后就感觉慢慢的懂了。所以,还是要动手去做。
中国有很多省份,而每个省份又包含了很多市,市里又包括县,县又包括乡或者镇,镇又包括很多村。那么要把这些数据放到一张表里怎么做呢?看看这些数据,是不是很像一颗树呢?有父节点也有子节点。所以我们就可以用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
一开始感觉这个递归查询不是很好理解,但是动手去敲,敲了几遍以后就感觉慢慢的懂了。所以,还是要动手去做。
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- 基于 Red Hat 的发行版 Oracle Linux 正式发布Oracle Linux 7.1
- 数据库链接字符串查询网站
- Oracle Containers for J2EE远程安全漏洞(CVE-2014-0413)
- Oracle 10g R2不能使用EM的问题
- 表空间操作
- PreparedStatement中in子句的处理
- VMware下RedHat4.8_64位安装Oracle 10g RAC--简略脚本
- oracle sql日期比较
- 基于 Red Hat 的发行版 Oracle Linux 正式发布Oracle Linux 7.1
- DB2实例管理
- DB2实例管理
- OS block size和Oracle block size,查找OS Blocksize的方法
- 保障MySQL数据安全的14个最佳方法
- mysql问答汇集
- oracle中创建数据库和表空间的几点总结
- 数据库自动备份脚本
- 创建一个空的IBM DB2 ECO数据库的方法