`
sizhefang
  • 浏览: 225935 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

CONNECT BY PRIOR... START WITH

    博客分类:
  • SQL
阅读更多

假设我们现在有如下结构的数据(T_Topic)

TopicID ParentID TopicTitle

1           null          请教Oracle 选取树状数据

2            1            re:请教Oracle 选取树状数据

3            1            其实只要这样就可以

4            1            我也有同样的问题,学习

5            1            顶!

6            5            不要发垃圾贴哦~

7            3            学习ing

8            3            不是Oracle的方法呀

9            6            我喜欢顶,咋地

10          9            封号!

 

 

大家注意看,上面的这些记录其实都是TopicID=1的纪录的相关记录(子记录或者孙记录,总归是后代记录)

我们现在需要使用一条语句选择以TopicID为1记录的全部后代记录,请看下面的SQL:

 

SELECT TopicID,ParentID,TopicTitle FROM T_TOPIC CONNECT BY PRIOR TopicID = ParentID START WITH TopciID = 1

通过这条SQL,我们就可以一次从Table中选取TopiID=1的纪录的全部后代记录及其自身。这条语句的关键部分就是 CONNECT BY PRIOR... START WITH,这句话的标准语法如下

 

SELECT FROM TABLENAME CONNECT BY {PRIOR 列名1 = 列名2 | 列名1 = PRIOR 列名2 } [START WITH];

CONNECT BY 关键字用于设定关联的两个字段,PRIOR 关键字用于设定优先参照字段,START WITH 关键字用于设定切入点。看到这三个关键字的说明,大家一定会想到一个问题,既然可以对不同的字段进行优先参照,那既然可以通过根节点选出其全部的子节点, 那么也应该可以通过子节点来选取其全部的祖先节点了,因为PRIOR的优先设定就是在设定其搜索的方向。如果PRIOR设定为自节点优先,则会选取本节点 的全部后代节点,反之如果PRIOR设定为父节点优先,就可以逆向得到全部的祖先节点了,还是以上面的数据为例,我们从“封号”这条记录作为切入点,使用 如下的SQL

 

SELECT TopicID,ParentID,TopicTitle FROM T_TOPIC CONNECT BY TopicID = PRIOR ParentID START WITH TopicID = 10

我们就能一次性选出如下的数据记录,也就是从“封号”这条记录开始的全部祖先节点

 

TopicID ParentID TopicTitle

10         9            封号!

9           6            我喜欢顶,咋地

6           5           不要发垃圾贴哦~

5          1            顶!

1          null         请教Oracle选取树状数据

 

以上我们就讲解了如何通过一个切入点找到某一个节点的全部后代节点或者全部祖先节 点,也许您会说了,我并不需要选取全部,我只要选两层,我的树只允许显示两层。嗯,没错,这也会是常见的需求之一,不过不要紧,我们可以通过加入一个新的 关键字 Level ,使用这个关键字,我们就可以控制被选出的关系层。具体的用法,我们还是以第二个SQL需求作为例子,现在假设是需要从“封号”这条数据向上找两层祖先节 点出来,该如何操作呢?让我们来看SQL

 

SELECT Topic,ParentID,TopicTitle FROM T_TOPIC WHERE LEVEL <= 3 CONNECT BY TopicID = PRIOR ParentID START WITH TopicID = 10

大家一定注意到了这条SQL中多了这样一段子句 LELVEL <= 3 ,这个就是用来限定选取层级的子句,这条子句就确保了我们可以选取包括节点以及其向上两层祖先节点一共三层节点。LEVEL 这个子句的变化也让你得到一些更加变态[-_-!]的结果,例如我只要取当前节点的祖父节点,那只要将 Level 设定为 Level = 3,去掉一个小于号就能满足一个变态的需求了 LEVEL 除了可以设定为普通的大于、小于、等于、大于等于、小于等于之外,甚至还可以设定为 BETWEEN X AND Y,实在是一个很不错的关键字,可以让我们满足很多变态的需求。

 

以上就是关于 CONNECTY BY ... PRIOR ... START WITH 的基本使用方法。当然了,用户的需求永远是BT的,不过我相信通过上面的这些基本应用的组合,一定可以满足大家的需求。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics