oracle数据库提供给了一个强大的功能:递归。
这功能目前在db2中是没有的。
1. 语法:
SELECT *
FROM TABLE_NAME T
START WITH T.CHILD_ID = '***'
CONNECT BY PRIOR T.CHILD_ID = T.PARENT_ID (注意:不能写成 CONNECT BY PRIOR T.PARENT_ID = T.CHILD_ID )
2.特别讲解:
START WITH T.CHILD_ID = '***'
这句话的意思是以 aaa 开始的行,如果在这个表中 CHILD_ID = 'aaa' 的数据有7行,并且PARENT_ID='aaa'的只有一条数据的时候,那么搜出来的结果集中,就 PARENT_ID='aaa' 的数据就有7条数据;
如果PARENT_ID='aaa'的数据有两条数据的话,那么搜出来的结果集中,就 PARENT_ID='aaa' 的数据就有14条数据;
如果PARENT_ID='aaa'的数据有两条数据的话,还希望搜出两条数据,那么就需要加上 DISTINCT 关键字(只会对 CHILD_ID ,PARENT_ID 两列起作用 )。
在大多数的情况下,CHILD_ID是不会有重复的,所以只要 CHILD_ID 不重复就可以不用加 DISTINCT 关键字,就可以得到我们想要的结果。
那么什么时候我们会用到刚才我讲到的情况呢,设置批次依赖的时候。批次依赖总是会遇到这种情况: A批次要同时依赖于B批次,C批次,D批次。
这时候就得这么设计表了
CHILD_ID PARENT_ID
A B
A C
A D
3.原则
start with 后面是头,头可以有多个,也可以有1个,这个看具体的需求了。
如何控制是多个还是一个呢,在 start with 后 加上 and 条件就可以了。
当然,后面的链条也可以按照需求加上你需要的 and 条件。
add by xingshi89 20130720
4. 死循环
这个是我昨天下午刚遇到的一个问题。
本来写的好好的sql 递归查询语句,以前用的好好的,并且也在生产上执行成功了,今天拿出来用居然不行了。
让我小郁闷了一把!!!
原因是在你的数据问题,而不是sql写的有问题,比如下面这种情况:
有一条数据: PARENT_ID = 1 ,CHILD_ID = 2678 ;
另一条数据: PARENT_ID = 2678 , CHILD_ID = 1 ;
这样的数据递归sql语句是不能执行的!oracle具体报错的错误代码我忘记了,这个也不重要了,重要的是大家要记得这种情况,到时候别怀疑自己的sql语句啊,呵呵