- 浏览: 1364578 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (551)
- 计划 (4)
- java (115)
- oracle (60)
- ajax (3)
- javascript (64)
- 计算机操作技巧集 (11)
- 近期关注话题 (10)
- 随想 (13)
- html (6)
- struts (15)
- hibernate (16)
- spring (2)
- game (0)
- Eglish (10)
- DisplayTag (6)
- jsp (18)
- css (3)
- eclipse (3)
- 其他知识 (8)
- 备用1 (12)
- 备用2 (1)
- 笑话-放松心情 (9)
- 设计 (1)
- 设计模式 (1)
- 数据结构 (0)
- office办公软件 (5)
- webwork (0)
- tomcat (2)
- MySql (1)
- 我的链接资源 (5)
- xml (2)
- servlet (0)
- PHP (13)
- DOM (0)
- 网页画图vml,canvas (1)
- 协议 (2)
- 健康 (3)
- 书籍下载 (1)
- jbpm (1)
- EXT (1)
- 自考 (2)
- 报表 (4)
- 生活 (64)
- 操作系统基础知识 (2)
- 测试 (2)
- guice (1)
- google学习 (2)
- Erlang (1)
- LOG4J (2)
- wicket (1)
- 考研 (1)
- 法律 (1)
- 地震 (1)
- 易学-等等相关 (1)
- 音乐 (1)
- 建站 (4)
- 分享说 (3)
- 购物省钱 (0)
- linux (1)
最新评论
-
zenmshuo:
如果使用SpreadJS这一类的表格工具,应该能更好的实现这些 ...
js中excel的用法 -
hjhj2991708:
第一个已经使用不了
jar包查询网站 非常好用! -
jiangmeiwei:
...
中文乱码 我的总结 不断更新 -
gary_bu:
...
response.sendRedirect 中文乱码问题解决 -
hnez:
多谢指点,怎么调试也不通,原来我在<body>&l ...
ExtJs IE ownerDocument.createRange() 错误解决方案
START WITH and CONNECT BY in Oracle SQL
摘自http://www.adp-gmbh.ch/ora/sql/connect_by.html
http://www.adp-gmbh.ch/
select ... start with initial-condition connect by nocycle recurse-condition
select ... connect by recurse-condition
select ... start with initial-condition connect by nocycle recurse-condition
select ... connect by recurse-condition
The start with .. connect by clause can be used to select data that has a hierarchical relationship (usually some sort of parent->child (boss->employee or thing->parts).
It is also being used when an sql execution plan is explained. recurse-condition can make use of the keyword prior:
connect by
prior foo = bar
This construct establishes the recursion. All records that are part of the next lower hierarchical level are found by having bar = foo. foo is a value found in the current hierarchical level.
A simple example
In the following example, the table from which that data is selected consists of just these attributes: parent and child. We make sure (by means of a unique constraint) that the child is uniqe within the table. This is just like in the real life where (as of yet) a child cannot have two different mothers. The data filled into the table is such that a the sum over the children with the same parent is the value of the parent:
set feedback off
create table test_connect_by (
parent number,
child number,
constraint uq_tcb unique (child)
);
5 = 2+3
insert into test_connect_by values ( 5, 2);
insert into test_connect_by values ( 5, 3);
18 = 11+7
insert into test_connect_by values (18,11);
insert into test_connect_by values (18, 7);
17 = 9+8
insert into test_connect_by values (17, 9);
insert into test_connect_by values (17,;
26 = 13+1+12
insert into test_connect_by values (26,13);
insert into test_connect_by values (26, 1);
insert into test_connect_by values (26,12);
15=10+5
insert into test_connect_by values (15,10);
insert into test_connect_by values (15, 5);
38=15+17+6
insert into test_connect_by values (38,15);
insert into test_connect_by values (38,17);
insert into test_connect_by values (38, 6);
38, 26 and 18 have no parents (the parent is null)
insert into test_connect_by values (null, 38);
insert into test_connect_by values (null, 26);
insert into test_connect_by values (null, 18);
Now, let's select the data hierarchically:
select lpad(' ',2*(level-1)) || to_char(child) s
from test_connect_by
start with parent is null
connect by prior child = parent;
This select statement results in:
38
15
10
5
2
3
17
9
8
6
26
13
1
12
18
11
7
Interpreting connect by statements
How must a start with ... connect by select statement be read and interpreted? If Oracle encounters such an SQL statement, it proceeds as described in the following pseude code.
for rec in (select * from some_table) loop
if FULLFILLS_START_WITH_CONDITION(rec) then
RECURSE(rec, rec.child);
end if;
end loop;
procedure RECURSE (rec in MATCHES_SELECT_STMT, new_parent IN field_type) is
begin
APPEND_RESULT_LIST(rec);
for rec_recurse in (select * from some_table) loop
if FULLFILLS_CONNECT_BY_CONDITION(rec_recurse.child, new_parent) then
RECURSE(rec_recurse,rec_recurse.child);
end if;
end loop;
end procedure RECURSE;
Thanks to Frank Trenkamp who spotted an error in the logic in the above pseudo code and corrected it.
Pruning branches
Sometimes, it might be a requirement to only partially retrieve a hierarchical tree and to prune branches. Here, a tree is filled. Each child is the number of its parent plus a new digit on the right side.
create table prune_test (
parent number,
child number
);
insert into prune_test values (null, 1);
insert into prune_test values (null, 6);
insert into prune_test values (null, 7);
insert into prune_test values ( 1, 12);
insert into prune_test values ( 1, 14);
insert into prune_test values ( 1, 15);
insert into prune_test values ( 6, 61);
insert into prune_test values ( 6, 63);
insert into prune_test values ( 6, 65);
insert into prune_test values ( 6, 69);
insert into prune_test values ( 7, 71);
insert into prune_test values ( 7, 74);
insert into prune_test values ( 12, 120);
insert into prune_test values ( 12, 124);
insert into prune_test values ( 12, 127);
insert into prune_test values ( 65, 653);
insert into prune_test values ( 71, 712);
insert into prune_test values ( 71, 713);
insert into prune_test values ( 71, 715);
insert into prune_test values ( 74, 744);
insert into prune_test values ( 74, 746);
insert into prune_test values ( 74, 748);
insert into prune_test values ( 712,7122);
insert into prune_test values ( 712,7125);
insert into prune_test values ( 712,7127);
insert into prune_test values ( 748,7481);
insert into prune_test values ( 748,7483);
insert into prune_test values ( 748,7487);
Now, we want to retrieve the tree, but prune everything below the branch 1 and 71. It would be false to put these into a where clause of the sql statement, rather, it belongs to the connect by clause:
select
lpad(' ', 2*level) || child
from
prune_test
start with
parent is null
connect by
prior child=parent
and parent not in (1, 71);
This returns:
1
6
61
63
65
653
69
7
71
74
744
746
748
7481
7483
7487
See also another example for pruning.
Do two items stand in a ancestor descendant relationship
Sometimes, one want's to know if two items are in an ancestor descendant relationship, that is if XYZ as grandfather, or grand-grandfather, or ... of ABC. The following template of a query can be used to determine that.
set feedback off
drop table parent_child;
create table parent_child(parent_ varchar2(20), child_ varchar2(20));
insert into parent_child values (null, 'a')
insert into parent_child values ( 'a', 'af');
insert into parent_child values ( 'a', 'ab');
insert into parent_child values ( 'a', 'ax');
insert into parent_child values ( 'ab', 'abc');
insert into parent_child values ( 'ab', 'abd');
insert into parent_child values ( 'ab', 'abe');
insert into parent_child values ('abe','abes');
insert into parent_child values ('abe','abet');
insert into parent_child values ( null, 'b');
insert into parent_child values ( 'b', 'bg');
insert into parent_child values ( 'b', 'bh');
insert into parent_child values ( 'b', 'bi');
insert into parent_child values ( 'bi', 'biq');
insert into parent_child values ( 'bi', 'biv');
insert into parent_child values ( 'bi', 'biw');
The following query 'asks' for a parent and a supposed child (grand child, grand grand child) and answers the question if the are indeed in an ancester successor relationship.
set verify off
select
case when count(*) > 0 then
'&&parent is an ancestor of &&child' else
'&&parent is no ancestor of &&child' end
"And here's the answer"
from
parent_child
where
child_ = '&&child'
start with
parent_ = '&&parent'
connect by
prior child_ = parent_;
undefine child
undefine parent
Features of 9i
sys_connect_by_path
With sys_connect_by_path it is possible to show the entire path from the top level down to the 'actual' child:
Using hierarchical result sets
With this technique, it is possible to show all kind of hierarchical data relations. Here is an example that lists privileges, roles and users in their hierarchical relation. See also flat hiearchy.
connect_by_root
connect_by_root is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries. I have yet to dig into this subject and will write about it when things become clearer.
connect_by_is_leaf
connect_by_isleaf is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries. I have yet to dig into this subject and will write about it when things become clearer.
connect_by_iscycle
connect_by_is_cycle is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries. I have yet to dig into this subject and will write about it when things become clearer.
Thanks
Thanks to Peter Bruhn, Jonathan Schmalze, Jeff Jones, Keith Britch and Fabian Iturralde who each pointed out an error, misstake or typo on this page.
Further links
On storing hierarchical data
摘自http://www.adp-gmbh.ch/ora/sql/connect_by.html
http://www.adp-gmbh.ch/
select ... start with initial-condition connect by nocycle recurse-condition
select ... connect by recurse-condition
select ... start with initial-condition connect by nocycle recurse-condition
select ... connect by recurse-condition
The start with .. connect by clause can be used to select data that has a hierarchical relationship (usually some sort of parent->child (boss->employee or thing->parts).
It is also being used when an sql execution plan is explained. recurse-condition can make use of the keyword prior:
connect by
prior foo = bar
This construct establishes the recursion. All records that are part of the next lower hierarchical level are found by having bar = foo. foo is a value found in the current hierarchical level.
A simple example
In the following example, the table from which that data is selected consists of just these attributes: parent and child. We make sure (by means of a unique constraint) that the child is uniqe within the table. This is just like in the real life where (as of yet) a child cannot have two different mothers. The data filled into the table is such that a the sum over the children with the same parent is the value of the parent:
set feedback off
create table test_connect_by (
parent number,
child number,
constraint uq_tcb unique (child)
);
5 = 2+3
insert into test_connect_by values ( 5, 2);
insert into test_connect_by values ( 5, 3);
18 = 11+7
insert into test_connect_by values (18,11);
insert into test_connect_by values (18, 7);
17 = 9+8
insert into test_connect_by values (17, 9);
insert into test_connect_by values (17,;
26 = 13+1+12
insert into test_connect_by values (26,13);
insert into test_connect_by values (26, 1);
insert into test_connect_by values (26,12);
15=10+5
insert into test_connect_by values (15,10);
insert into test_connect_by values (15, 5);
38=15+17+6
insert into test_connect_by values (38,15);
insert into test_connect_by values (38,17);
insert into test_connect_by values (38, 6);
38, 26 and 18 have no parents (the parent is null)
insert into test_connect_by values (null, 38);
insert into test_connect_by values (null, 26);
insert into test_connect_by values (null, 18);
Now, let's select the data hierarchically:
select lpad(' ',2*(level-1)) || to_char(child) s
from test_connect_by
start with parent is null
connect by prior child = parent;
This select statement results in:
38
15
10
5
2
3
17
9
8
6
26
13
1
12
18
11
7
Interpreting connect by statements
How must a start with ... connect by select statement be read and interpreted? If Oracle encounters such an SQL statement, it proceeds as described in the following pseude code.
for rec in (select * from some_table) loop
if FULLFILLS_START_WITH_CONDITION(rec) then
RECURSE(rec, rec.child);
end if;
end loop;
procedure RECURSE (rec in MATCHES_SELECT_STMT, new_parent IN field_type) is
begin
APPEND_RESULT_LIST(rec);
for rec_recurse in (select * from some_table) loop
if FULLFILLS_CONNECT_BY_CONDITION(rec_recurse.child, new_parent) then
RECURSE(rec_recurse,rec_recurse.child);
end if;
end loop;
end procedure RECURSE;
Thanks to Frank Trenkamp who spotted an error in the logic in the above pseudo code and corrected it.
Pruning branches
Sometimes, it might be a requirement to only partially retrieve a hierarchical tree and to prune branches. Here, a tree is filled. Each child is the number of its parent plus a new digit on the right side.
create table prune_test (
parent number,
child number
);
insert into prune_test values (null, 1);
insert into prune_test values (null, 6);
insert into prune_test values (null, 7);
insert into prune_test values ( 1, 12);
insert into prune_test values ( 1, 14);
insert into prune_test values ( 1, 15);
insert into prune_test values ( 6, 61);
insert into prune_test values ( 6, 63);
insert into prune_test values ( 6, 65);
insert into prune_test values ( 6, 69);
insert into prune_test values ( 7, 71);
insert into prune_test values ( 7, 74);
insert into prune_test values ( 12, 120);
insert into prune_test values ( 12, 124);
insert into prune_test values ( 12, 127);
insert into prune_test values ( 65, 653);
insert into prune_test values ( 71, 712);
insert into prune_test values ( 71, 713);
insert into prune_test values ( 71, 715);
insert into prune_test values ( 74, 744);
insert into prune_test values ( 74, 746);
insert into prune_test values ( 74, 748);
insert into prune_test values ( 712,7122);
insert into prune_test values ( 712,7125);
insert into prune_test values ( 712,7127);
insert into prune_test values ( 748,7481);
insert into prune_test values ( 748,7483);
insert into prune_test values ( 748,7487);
Now, we want to retrieve the tree, but prune everything below the branch 1 and 71. It would be false to put these into a where clause of the sql statement, rather, it belongs to the connect by clause:
select
lpad(' ', 2*level) || child
from
prune_test
start with
parent is null
connect by
prior child=parent
and parent not in (1, 71);
This returns:
1
6
61
63
65
653
69
7
71
74
744
746
748
7481
7483
7487
See also another example for pruning.
Do two items stand in a ancestor descendant relationship
Sometimes, one want's to know if two items are in an ancestor descendant relationship, that is if XYZ as grandfather, or grand-grandfather, or ... of ABC. The following template of a query can be used to determine that.
set feedback off
drop table parent_child;
create table parent_child(parent_ varchar2(20), child_ varchar2(20));
insert into parent_child values (null, 'a')
insert into parent_child values ( 'a', 'af');
insert into parent_child values ( 'a', 'ab');
insert into parent_child values ( 'a', 'ax');
insert into parent_child values ( 'ab', 'abc');
insert into parent_child values ( 'ab', 'abd');
insert into parent_child values ( 'ab', 'abe');
insert into parent_child values ('abe','abes');
insert into parent_child values ('abe','abet');
insert into parent_child values ( null, 'b');
insert into parent_child values ( 'b', 'bg');
insert into parent_child values ( 'b', 'bh');
insert into parent_child values ( 'b', 'bi');
insert into parent_child values ( 'bi', 'biq');
insert into parent_child values ( 'bi', 'biv');
insert into parent_child values ( 'bi', 'biw');
The following query 'asks' for a parent and a supposed child (grand child, grand grand child) and answers the question if the are indeed in an ancester successor relationship.
set verify off
select
case when count(*) > 0 then
'&&parent is an ancestor of &&child' else
'&&parent is no ancestor of &&child' end
"And here's the answer"
from
parent_child
where
child_ = '&&child'
start with
parent_ = '&&parent'
connect by
prior child_ = parent_;
undefine child
undefine parent
Features of 9i
sys_connect_by_path
With sys_connect_by_path it is possible to show the entire path from the top level down to the 'actual' child:
Using hierarchical result sets
With this technique, it is possible to show all kind of hierarchical data relations. Here is an example that lists privileges, roles and users in their hierarchical relation. See also flat hiearchy.
connect_by_root
connect_by_root is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries. I have yet to dig into this subject and will write about it when things become clearer.
connect_by_is_leaf
connect_by_isleaf is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries. I have yet to dig into this subject and will write about it when things become clearer.
connect_by_iscycle
connect_by_is_cycle is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries. I have yet to dig into this subject and will write about it when things become clearer.
Thanks
Thanks to Peter Bruhn, Jonathan Schmalze, Jeff Jones, Keith Britch and Fabian Iturralde who each pointed out an error, misstake or typo on this page.
Further links
On storing hierarchical data
发表评论
-
oracle删除重复记录
2009-07-16 11:16 1215有困难,找猪八戒 Q:要删除一张表中的重复记录,但是要保留一条 ... -
db2 express-c 安装后检查及安装例子数据库
2009-02-27 17:07 3394摘自http://publib.boulder.ibm.com ... -
问:如何得到与WEB-INF同级目录下的配置文件
2008-09-23 08:35 2134Q: 有如下需求:需要从WEB-INF同级的目录下读取配 ... -
讨论如何优化这条sql
2008-09-11 16:33 1597SELECT * FROM ( ... -
N Vs Exist in SQL
2008-07-02 16:39 1393N Vs Exist in SQL 原文如下: http:// ... -
SQL 指南
2008-05-27 11:45 1047http://www.sql-tutorial.com/ -
orace 分析函数
2008-05-26 09:08 1212select x.num, sum(x.num) over ( ... -
oralce tutoial 指南
2008-03-22 14:21 1031http://www.exforsys.com/tutoria ... -
查找部分字段重复的记录 ORACLE Identifying duplicate rows
2008-03-13 08:49 1967http://www.jlcomp.demon.co.uk/f ... -
oracle 资源网站
2008-01-12 11:42 1877oracle alter table table_ ... -
Top 5 Oracle Reference Books 前5本 oracle 参考书
2008-01-12 11:24 1718http://databases.about.com/od/o ... -
Oracle与DB2、MySQL取前10条记录的对比<转>
2008-01-11 16:46 2221原文:http://tech.ccidnet.com/art/ ... -
expert on e on one oracle - Thomas Kyte 读书笔记
2008-01-11 10:17 2111=============================== ... -
oracle 资源 整体理解oralce 比较好 英文网
2008-01-09 16:59 1193http://www.adp-gmbh.ch/ora/admi ... -
oracle java 插入 clob insert clob hibernate
2007-12-21 15:48 7230用jdbc 或者 hibernate http://www.w ... -
pl/sql 应用之一
2007-12-12 17:21 1138declare begin insert into x ... -
init.ora文件所在目录
2007-12-12 15:58 2167Oracle安装盘:\oracle\admin\DB名称\pf ... -
[Oracle] 如何解决ORA-04031 错误
2007-12-12 15:53 3254[Oracle] 如何解决ORA-04031 ... -
oracle faq 常见问题解答 http://www.orafaq.com/
2007-12-12 13:34 1499The Oracle FAQ http://www.oraf ... -
oracle 快速参考
2007-12-12 09:58 1095http://www.psoug.org/library.ht ...
相关推荐
### Oracle Start With.Connect By Prior 子句实现递归查询 #### 概述 在Oracle数据库中,`Start With.Connect By Prior`子句是执行递归查询的一种强大工具,主要用于处理层次结构数据。这类数据通常存在于组织...
### Oracle数据库中的START WITH 和 CONNECT BY 用法详解 在Oracle数据库中,处理层次结构数据时,`START WITH` 和 `CONNECT BY` 是非常有用的两个关键字。这些关键字可以帮助我们在查询时构建出树形或者层级结构的...
Oracle 查询树型关系是指使用 START WITH 和 CONNECT BY 子句来实现 SQL 的层次查询。从 Oracle 9i 开始,可以通过 SYS_CONNECT_BY_PATH 函数实现将父节点到当前行内容以“path”或者层次元素列表的形式显示出来。 ...
### Oracle中的START WITH CONNECT BY PRIOR 用法详解 #### 一、概念介绍 在Oracle数据库中,`START WITH` 和 `CONNECT BY PRIOR` 是两个非常强大的特性,主要用于处理具有层级结构的数据。这两个特性可以帮助我们...
[ WHERE condition ][ [ START WITH condition ] CONNECT BY condition [ ORDER SIBLINGS BY expression ] ] ``` 其中,`START WITH`子句用于指定查询的起始节点,`CONNECT BY`子句用于指定查询的递归条件。 ...
`START WITH...CONNECT BY PRIOR`是Oracle SQL中的一个特性,用于处理具有层级关系的数据。这个子句允许我们遍历和查询具有父子关系的数据,例如部门和其下属子部门,或者员工和他们的上级经理。 1. **START WITH...
Oracle 连接查询是指使用 START WITH 和 CONNECT BY 语句来实现递归查询的方法,这种方法可以生成树形结构的数据。在 Oracle 中,START WITH 语句用于指定递归查询的开始记录,而 CONNECT BY 语句用于指定递归查询的...
通常,`CONNECT BY`与`START WITH`一起使用,`START WITH`指定了层级遍历的起始节点。 例如,假设我们有一个员工表(EMPLOYEE),其中包含上级员工ID(MANAGER_ID)字段,我们可以使用以下查询来展示员工的管理层次...
Oracle数据库通过提供`START WITH...CONNECT BY`语句来简化这类查询操作。此功能最早出现在Oracle 8.1.6版本,并一直沿用至今,成为处理递归查询的强大工具之一。 #### 二、Connect By与Start With详解 1. **...
可以看到,Oracle的SELECT语句支持更多的子句,例如START WITH U CONNECT BY、INTERSECT和MINUS等。这些子句在SqlServer中不支持,但是可以使用其他方式实现相同的结果。 二、函数和过程 Oracle和SqlServer都支持...
在Oracle数据库中,递归查询可以通过`START WITH CONNECT BY PRIOR`语句实现。此语句允许用户按照树状结构来检索数据。 ##### 1. `START WITH CONNECT BY PRIOR`用法详解 **基本语法**: ```sql SELECT * FROM ...
START WITH U CONNECT BY {...} ``` - **SQL Server:** SQL Server提供了类似的SELECT语句结构,但并不支持`START WITH ... CONNECT BY` 子句。为了实现层次结构查询,可以使用递归公共表表达式(Recursive CTEs...
在Oracle中,`START WITH` 和 `CONNECT BY` 是进行递归查询的关键字,它们允许我们从一个特定的根节点出发,沿着预定义的关系链接遍历整个树形结构。本文将深入探讨这两个关键字的用法,并通过实例来说明其在实际...
- **层次查询**:使用`CONNECT BY`和`START WITH`子句进行层次结构查询。 ```sql SELECT employee_name, manager_name FROM employees START WITH manager_name IS NULL CONNECT BY PRIOR employee_name = ...
在SQL查询中,`START WITH` 和 `CONNECT BY` 是两个关键的子句,它们用于构建层次结构查询,通常在处理具有上下级关系的数据时非常有用,如员工与经理的关系、组织结构或者产品分类等。这两个子句是Oracle数据库特有...
CONNECT BY [NOCYCLE] condition [AND condition] [START WITH condition] START WITH condition CONNECT BY [NOCYCLE] condition [AND condition] ``` 其中,`START WITH`用于指定查询的起始节点,而`CONNECT BY`...
递归树形结构查询主要依赖于`CONNECT BY`和`PRIOR`关键字,它们允许我们构建复杂的层级查询,以展示数据的层次关系。 在Oracle中,树形结构查询的基本语法如下: ```sql SELECT [LEVEL], * FROM table_name START ...
- Oracle 的 `START WITH U CONNECT BY` 用于创建层次查询,SQL Server 可以通过递归公共表表达式(CTE)或存储过程实现类似功能。 - Oracle 支持 `INTERSECT` 和 `MINUS` 集合运算符,而 SQL Server 用 `EXISTS` 和...
CONNECT BY PRIOR empno = mgr AND ename != 'SCOTT'; ``` ##### 7. 增加过滤条件 可以在`WHERE`子句中增加额外的过滤条件,例如筛选薪水高于2500的员工: ```sql SELECT LEVEL, LPAD(' ', 2 * LEVEL - 1) || ename...