[quote][size=small] 这些天做的是分类工作,其中用到了数据库保存树形结构的数据,就是在一个数据库表中储存了多棵树。比如在数据库表“分类表”中有“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子句,改变查询结果的显示顺序。
[/size][/quote]
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子句,改变查询结果的显示顺序。
[/size][/quote]