论坛首页 综合技术论坛

Orcale的树形查询

浏览 4368 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-08-13   最后修改:2010-03-26
引用
    这些天做的是分类工作,其中用到了数据库保存树形结构的数据,就是在一个数据库表中储存了多棵树。比如在数据库表“分类表”中有“ID”,“父ID”和“分类名称”三个字段。以下是表结构和数据。

ID    父ID    分类名称
1               A
2      1       B
3      1       C
4      2       D
5      2       E
6      3       F
7      3       H

    扫描树结构表时,需要依此访问树结构的每个节点,一个节点只能访问一次,其访问的步骤如下:

第一步:从根节点开始;

第二步:访问该节点;

第三步:判断该节点有无未被访问的子节点,若有,则转向它最左侧的未被访问的子节,并执行第二步,否则执行第四步;

第四步:若该节点为根节点,则访问完毕,否则执行第五步;

第五步:返回到该节点的父节点,并执行第三步骤。

    从这张表中我们可以知道表中有一棵树,我们要查询这棵树的叶子节点的orcale sql代码是:

select rpad(' ', 2*(level-1), ' ') || t.分类名称 "Name",

        connect_by_root t.分类名称 "Root",

        connect_by_isleaf "IsLeaf",

        level "Level",

        sys_connect_by_path(t.分类名称, '/') "Path"

    from 分类表 t

    where connect_by_isleaf=0

    start with t.父id is null

    connect by prior t.id = t.父id
    
    order by t.id


下面我们来解释下这个sql中的语法,函数,操作符。

1.语法:

SELECT sql_expn FROM [user.]table

WHERE where_condition

START WITH expn = expn

CONNECT BY [PRIOR] expn = [PRIOR] expn

ORDER BY expn

变量:
sql_expn:有效的SQL表达式

user:表的主人

table:  查询的表名

where_condition:查询的条件

expn:任意有效的表达式


2.函数

    1) rpad(char1,n,char2):行数用在字符串char1的右端填充字符串char2,直至字符串的总长度为n,char2的默认值为空格。如果char1的长度大于n,则该行数返回char1左端的n个字符。
    2) sys_connect_by_path(字段名, 2个字段之间的连接符号):树结构和它的专用函数,用来显示分支的路径。注意这里的连接符号不要使用逗号,oracle会报错,如果一定要用,可以使用replace替换一下,方法如下 REPLACE(字段名,原字符,',')。还有,这个函数使用之前必须先建立一个树,否则无用。

3.运算符
    1) prior:被放置于等号前后的位置,决定着查询时的检索顺序。
PRIOR被置于CONNECT BY子句中等号的前面时,则强制从根节点到叶节点的顺序检索,即由父节点向子节点方向通过树结构,我们称之为自顶向下的方式。例如:
CONNECT BY PRIOR id = 父id
PIROR运算符被置于CONNECT BY 子句中等号的后面时,则强制从叶节点到根节点的顺序检索,即由子节点向父节点方向通过树结构,我们称之为自底向上的方式。例如:
CONNECT BY id=PRIOR 父id
   
    2) connect by:说明每行数据将是按层次顺序检索,并规定将表中的数据连入树型结构的关系中。PRIORY运算符必须放置在连接关系的两列中某一个的前面。对于节点间的父子关系,PRIOR运算符在一侧表示父节点,在另一侧表示子节点,从而确定查找树结构是的顺序是自顶向下还是自底向上。在连接关系中,除了可以使用列名外,还允许使用列表达式。START WITH 子句为可选项,用来标识哪个节点作为查找树型结构的根节点。若该子句被省略,则表示所有满足查询条件的行作为根节点。
   
    3) start with:不但可以指定一个根节点,还可以指定多个根节点
   
    4) level:在具有树结构的表中,每一行数据都是树结构中的一个节点,由于节点所处的层次位置不同,所以每行记录都可以有一个层号。层号根据节点与根节点的距离确定。不论从哪个节点开始,该起始根节点的层号始终为1,根节点的子节点为2, 依此类推。

    5) connect_by_root:用在列名之前返回当前层的根节点(最高级节点的内容)

    6) connect_by_isleaf:来判断当前行是不是叶子,如果是叶子就会在伪列中显示1,否则显示 0。

    7) connect_by_iscycle:10g中增加对树中环状循环的处理;一旦数据中出现了循环记录(如:两个节点互为对方父节点),在10g以前版本的数据库中会错误提示“ora-01436”,只要指定 nocycle 可避免报错,且通过connect_by_iscycle属性就知道哪些节点产生了循环,如果出现循环,connect_by_iscycle伪列显示为1,否则显示为0。

4.其他
    1) 节点和分支的裁剪:在对树结构进行查询时,可以去掉表中的某些行,也可以剪掉树中的一个分支,使用WHERE子句来限定树型结构中的单个节点,以去掉树中的单个节点,但它却不影响其后代节点(自顶向下检索时)或前辈节点(自底向顶检索时)。

    2) 排序显示:order by子句,改变查询结果的显示顺序。


论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics