ITPUB论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1542|回复: 8

connect by 使用总结 [复制链接]

注册会员

高级会员

精华贴数
1
技术积分
10851
社区积分
52
注册时间
2006-7-30
论坛徽章:
24
生肖徽章:狗
日期:2006-09-07 10:14:43数据库板块每日发贴之星
日期:2008-07-26 01:02:20生肖徽章2007版:兔
日期:2008-10-13 11:10:112008北京奥运纪念徽章:铁人三项
日期:2008-10-24 13:27:21开发板块每日发贴之星
日期:2008-12-27 01:01:09生肖徽章2007版:马
日期:2009-11-18 10:45:032010新春纪念徽章
日期:2010-03-01 11:21:02ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51ERP板块每日发贴之星
日期:2011-05-18 01:01:012012新春纪念徽章
日期:2012-01-04 11:51:22数据库板块每日发贴之星
日期:2008-02-29 01:04:112008新春纪念徽章
日期:2008-02-13 12:43:03
发表于 2007-1-31 21:43:14 |显示全部楼层
对于使用sys_connect_by_path函数来得到树型结构信息的平铺,但是使用过程中发现,有很多实现了但是查出来的数据不对。

如:
select deptno,ltrim(sys_connect_by_path(ename,','),',') path from (
    select deptno,ename,row_number() over (order by deptno) node_id,
    row_number() over (partition by deptno order by deptno) rn from emp
    )
    start with rn=1
    connect by node_id- 1 = prior node_id

1        10        CLARK
2        10        CLARK,KING
3        10        CLARK,KING,MILLER
4        20        CLARK,KING,MILLER,SMITH
5        20        CLARK,KING,MILLER,SMITH,ADAMS
6        20        CLARK,KING,MILLER,SMITH,ADAMS,FORD
7        20        CLARK,KING,MILLER,SMITH,ADAMS,FORD,SCOTT
8        20        CLARK,KING,MILLER,SMITH,ADAMS,FORD,SCOTT,JONES
9        30        CLARK,KING,MILLER,SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN
10        30        CLARK,KING,MILLER,SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE
11        30        CLARK,KING,MILLER,SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN
12        30        CLARK,KING,MILLER,SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN,JAMES
13        30        CLARK,KING,MILLER,SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN,JAMES,TURNER
14        30        CLARK,KING,MILLER,SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN,JAMES,TURNER,WARD
15        20        SMITH
16        20        SMITH,ADAMS
17        20        SMITH,ADAMS,FORD
18        20        SMITH,ADAMS,FORD,SCOTT
19        20        SMITH,ADAMS,FORD,SCOTT,JONES
20        30        SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN
21        30        SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE
22        30        SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN
23        30        SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN,JAMES
24        30        SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN,JAMES,TURNER
25        30        SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN,JAMES,TURNER,WARD
26        30        ALLEN
27        30        ALLEN,BLAKE
28        30        ALLEN,BLAKE,MARTIN
29        30        ALLEN,BLAKE,MARTIN,JAMES
30        30        ALLEN,BLAKE,MARTIN,JAMES,TURNER
31        30        ALLEN,BLAKE,MARTIN,JAMES,TURNER,WARD

通常为了满足结果,我们都取最大的,可是问题出现了。

select deptno,ltrim(max(sys_connect_by_path(ename,',')),',') path from (
    select deptno,ename,row_number() over (order by deptno) node_id,
    row_number() over (partition by deptno order by deptno) rn from emp
    )
    start with rn=1
    connect by node_id- 1 = prior node_id
    group by deptno

1        10        CLARK,KING,MILLER
2        20        SMITH,ADAMS,FORD,SCOTT,JONES
3        30        SMITH,ADAMS,FORD,SCOTT,JONES,ALLEN,BLAKE,MARTIN,JAMES,TURNER,WARD

请看部门30的雇员名称,多了其他部门的人,为什么呢。
因为我们构建连接的条件是node_id- 1 = prior node_id,看下连接前的信息。

select deptno,ename,row_number() over (order by deptno) node_id,
    row_number() over (partition by deptno order by deptno) rn from emp

1        10        CLARK        1        1
2        10        KING        2        2
3        10        MILLER        3        3
4        20        SMITH        4        1
5        20        ADAMS        5        2
6        20        FORD        6        3
7        20        SCOTT        7        4
8        20        JONES        8        5
9        30        ALLEN        9        1
10        30        BLAKE        10        2
11        30        MARTIN        11        3
12        30        JAMES        12        4
13        30        TURNER        13        5
14        30        WARD        14        6


这样,第一个部门10,遍历10、20、30的记录,部门20遍历20、30的记录,部门30遍历30自己的记录,这样再求最大的时候,可能就会出错了。

解决办法是:
select deptno,ltrim(max(sys_connect_by_path(ename,',')),',') path from (
    select deptno,ename,2*row_number() over (order by deptno) - row_number() over (partition by deptno order by deptno) node_id,
    row_number() over (partition by deptno order by deptno) rn from emp
    )
    start with rn=1
    connect by node_id- 1 = prior node_id
    group by deptno

注意上面的2*row_number() over (order by deptno) - row_number() over (partition by deptno order by deptno) node_id,这样就分隔了各个部门的数据联系了。看下连接前的信息

1        10        CLARK        1        1
2        10        KING        2        2
3        10        MILLER        3        3
4        20        SMITH        7        1
5        20        ADAMS        8        2
6        20        FORD        9        3
7        20        SCOTT        10        4
8        20        JONES        11        5
9        30        ALLEN        17        1
10        30        BLAKE        18        2
11        30        MARTIN        19        3
12        30        JAMES        20        4
13        30        TURNER        21        5
14        30        WARD        22        6

各个部门之间的数据是断开的,而且各部门内也能满足连接条件node_id- 1 = prior node_id。这样处理后查询处理的信息如下:

1        10        CLARK
2        10        CLARK,KING
3        10        CLARK,KING,MILLER
4        20        SMITH
5        20        SMITH,ADAMS
6        20        SMITH,ADAMS,FORD
7        20        SMITH,ADAMS,FORD,SCOTT
8        20        SMITH,ADAMS,FORD,SCOTT,JONES
9        30        ALLEN
10        30        ALLEN,BLAKE
11        30        ALLEN,BLAKE,MARTIN
12        30        ALLEN,BLAKE,MARTIN,JAMES
13        30        ALLEN,BLAKE,MARTIN,JAMES,TURNER
14        30        ALLEN,BLAKE,MARTIN,JAMES,TURNER,WARD

emp表一共14条记录,这样连接出来的也是14条,而上面的连接出现了31条。这样统一的处理方法就是上面的一个小小的技巧了。

希望对大家能有帮助!

精华贴数
8
技术积分
10997
社区积分
930
注册时间
2002-1-6
论坛徽章:
63
生肖徽章2007版:羊
日期:2008-11-14 14:42:19迷宫蛋
日期:2011-05-10 13:03:40蛋疼蛋
日期:2011-05-10 13:03:56复活蛋
日期:2011-05-10 13:04:092010广州亚运会纪念徽章:三项全能
日期:2011-05-19 21:32:30复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20
发表于 2007-2-1 09:31:09 |显示全部楼层
其实只要在Connect By子句中增加一个部门的条件就可以了。
connect by node_id - 1 = prior node_id and deptno = prior deptno

使用道具 举报

注册会员

妮露 ! i LIKE

精华贴数
1
技术积分
16855
社区积分
19000
注册时间
2004-11-12
论坛徽章:
105
生肖徽章:鸡
日期:2006-12-02 12:25:43生肖徽章:鼠
日期:2007-02-10 06:34:13生肖徽章2007版:鸡
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:53生肖徽章2007版:羊
日期:2009-03-10 21:21:58祖国60周年纪念徽章
日期:2009-10-09 08:28:00祖国60周年纪念徽章
日期:2009-10-09 08:28:00
发表于 2007-2-1 09:39:49 |显示全部楼层
学习,我可以收藏转贴么

使用道具 举报

注册会员

高级会员

精华贴数
1
技术积分
10851
社区积分
52
注册时间
2006-7-30
论坛徽章:
24
生肖徽章:狗
日期:2006-09-07 10:14:43数据库板块每日发贴之星
日期:2008-07-26 01:02:20生肖徽章2007版:兔
日期:2008-10-13 11:10:112008北京奥运纪念徽章:铁人三项
日期:2008-10-24 13:27:21开发板块每日发贴之星
日期:2008-12-27 01:01:09生肖徽章2007版:马
日期:2009-11-18 10:45:032010新春纪念徽章
日期:2010-03-01 11:21:02ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51ERP板块每日发贴之星
日期:2011-05-18 01:01:012012新春纪念徽章
日期:2012-01-04 11:51:22数据库板块每日发贴之星
日期:2008-02-29 01:04:112008新春纪念徽章
日期:2008-02-13 12:43:03
发表于 2007-2-1 09:49:10 |显示全部楼层
最初由 nyfor 发布
[B]其实只要在Connect By子句中增加一个部门的条件就可以了。
connect by node_id - 1 = prior node_id and deptno = prior deptno [/B]



学习了!

使用道具 举报

注册会员

俺不是会员

精华贴数
5
技术积分
4819
社区积分
9193
注册时间
2005-4-4
论坛徽章:
51
ITPUB9周年纪念徽章
日期:2010-10-08 09:28:522011新春纪念徽章
日期:2011-02-18 11:43:342010广州亚运会纪念徽章:举重
日期:2011-04-14 16:25:19
发表于 2007-2-1 10:38:27 |显示全部楼层
LZ挺强。。。。。。。。。
俺慢慢学习一下。

使用道具 举报

注册会员

高级会员

精华贴数
1
技术积分
10851
社区积分
52
注册时间
2006-7-30
论坛徽章:
24
生肖徽章:狗
日期:2006-09-07 10:14:43数据库板块每日发贴之星
日期:2008-07-26 01:02:20生肖徽章2007版:兔
日期:2008-10-13 11:10:112008北京奥运纪念徽章:铁人三项
日期:2008-10-24 13:27:21开发板块每日发贴之星
日期:2008-12-27 01:01:09生肖徽章2007版:马
日期:2009-11-18 10:45:032010新春纪念徽章
日期:2010-03-01 11:21:02ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51ERP板块每日发贴之星
日期:2011-05-18 01:01:012012新春纪念徽章
日期:2012-01-04 11:51:22数据库板块每日发贴之星
日期:2008-02-29 01:04:112008新春纪念徽章
日期:2008-02-13 12:43:03
发表于 2007-2-1 10:41:04 |显示全部楼层
最初由 freeka 发布
[B]学习,我可以收藏转贴么 [/B]


java不是都讲究开源么?可以转啊

说明出处就好了!

使用道具 举报

注册会员

高级会员

精华贴数
1
技术积分
10851
社区积分
52
注册时间
2006-7-30
论坛徽章:
24
生肖徽章:狗
日期:2006-09-07 10:14:43数据库板块每日发贴之星
日期:2008-07-26 01:02:20生肖徽章2007版:兔
日期:2008-10-13 11:10:112008北京奥运纪念徽章:铁人三项
日期:2008-10-24 13:27:21开发板块每日发贴之星
日期:2008-12-27 01:01:09生肖徽章2007版:马
日期:2009-11-18 10:45:032010新春纪念徽章
日期:2010-03-01 11:21:02ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51ERP板块每日发贴之星
日期:2011-05-18 01:01:012012新春纪念徽章
日期:2012-01-04 11:51:22数据库板块每日发贴之星
日期:2008-02-29 01:04:112008新春纪念徽章
日期:2008-02-13 12:43:03
发表于 2007-2-4 17:09:28 |显示全部楼层
学习了!

使用道具 举报

注册会员

淡泊明志 宁静志远

精华贴数
1
技术积分
7285
社区积分
1126
注册时间
2003-2-12
论坛徽章:
12
ITPUB元老
日期:2006-12-29 17:11:00生肖徽章2007版:猴
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:532009新春纪念徽章
日期:2009-01-04 14:52:28祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:21:02ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
发表于 2007-2-5 11:37:37 |显示全部楼层
select deptno, ltrim(sys_connect_by_path(ename, ','), ',') path
  from (select deptno,
               ename,
               2 * row_number() over(order by deptno) - row_number() over(partition by deptno order by deptno) node_id,
               row_number() over(partition by deptno order by deptno) rn
          from emp)
start with rn = 1
connect by node_id - 1 = prior node_id
group by deptno
这样做不行吧

使用道具 举报

注册会员

高级会员

精华贴数
1
技术积分
10851
社区积分
52
注册时间
2006-7-30
论坛徽章:
24
生肖徽章:狗
日期:2006-09-07 10:14:43数据库板块每日发贴之星
日期:2008-07-26 01:02:20生肖徽章2007版:兔
日期:2008-10-13 11:10:112008北京奥运纪念徽章:铁人三项
日期:2008-10-24 13:27:21开发板块每日发贴之星
日期:2008-12-27 01:01:09生肖徽章2007版:马
日期:2009-11-18 10:45:032010新春纪念徽章
日期:2010-03-01 11:21:02ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51ERP板块每日发贴之星
日期:2011-05-18 01:01:012012新春纪念徽章
日期:2012-01-04 11:51:22数据库板块每日发贴之星
日期:2008-02-29 01:04:112008新春纪念徽章
日期:2008-02-13 12:43:03
发表于 2007-2-5 12:01:20 |显示全部楼层
最初由 cyr1974 发布
[B]select deptno, ltrim(sys_connect_by_path(ename, ','), ',') path
  from (select deptno,
               ename,
               2 * row_number() over(order by deptno) - row_number() over(partition by deptno order by deptno) node_id,
               row_number() over(partition by deptno order by deptno) rn
          from emp)
start with rn = 1
connect by node_id - 1 = prior node_id
group by deptno
这样做不行吧 [/B]


缺少个max函数,已更改,多谢指正!

使用道具 举报

相关内容推荐
您需要登录后才可以回帖 登录 | 注册

TOP技术积分榜 社区积分榜 徽章 电子杂志 团队 统计 邮箱 虎吧 老博客 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档 | IT博客
CopyRight 1999-2011 itpub.net All Right Reserved. 北京皓辰网域网络信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001 广播电视节目制作经营许可证:编号(京)字第1149号
  
回顶部