• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Myth's space
好好学习,不见进步
博客园    首页    新随笔    联系   管理    订阅  订阅

深入了解start with .....connect by (一)

一个来自ITPUB帖子的启示
START WITH . . . CONNECT BY . . .子句常用来实现SQL的层次查询.刚才看到一个蛮有趣的帖子,楼主用了数学方法深入研究了connect by
原帖子如下。

对于connect by,现在大多数人已经很熟悉了
connect by中的条件就表示了父子之间的连接关系
比如 connect by id=prior pid

但如果connect by中的条件没有表示记录之间的父子关系
那会出现什么情况?
常见的,connect by会在构造序列的时候使用
用select rownum from dual connect by rownum<xxx 代替早期版本的 select rownum from all_objects where rownum <xxx

我们注意到,dual是一个只有一条记录的表,如果表有多条记录,将会怎样?

下面开始实验
环境:windows xp sp2 + Oracle 9208
(10.1版本connect by有问题)

CREATE TABLE T
(
  ID  
VARCHAR2(1 BYTE)
);

INSERT INTO T ( ID ) VALUES (
'A');
INSERT INTO T ( ID ) VALUES (
'B');
INSERT INTO T ( ID ) VALUES (
'C');
COMMIT;


SQL
> select rownum from dual connect by rownum<10;

    ROWNUM
----------
         1
         
2
         
3
         
4
         
5
         
6
         
7
         
8
         
9

9 rows selected.

SQL
> select id,level from t connect by level<2;

I      
LEVEL
- ----------
A          1
B          
1
C          
1

SQL
> select id,level from t connect by level<3;

I      
LEVEL
- ----------
A          1
A          
2
B          
2
C          
2
B          
1
A          
2
B          
2
C          
2
C          
1
A          
2
B          
2

I      
LEVEL
- ----------
C          2

12 rows selected.

SQL
> select id,level from t connect by level<4;

I      
LEVEL
- ----------
A          1
A          
2
A          
3
B          
3
C          
3
B          
2
A          
3
B          
3
C          
3
C          
2
A          
3

I      
LEVEL
- ----------
B          3
C          
3
B          
1
A          
2
A          
3
B          
3
C          
3
B          
2
A          
3
B          
3
C          
3

I      
LEVEL
- ----------
C          2
A          
3
B          
3
C          
3
C          
1
A          
2
A          
3
B          
3
C          
3
B          
2
A          
3

I      
LEVEL
- ----------
B          3
C          
3
C          
2
A          
3
B          
3
C          
3

39 rows selected.

SQL
>

无需多说,我们很快可以找到其中的规律,假设表中有N条记录
则记F(N,l)为 select id,level from t connect by level<l 的结果集数目
那么,
F(N,1)=N
F(N,l) = F(N,l-1)*N+N

于是可以总结出
F(N,l)=∑power(N,p), p取值为[1,l)


要解释,也很容易
当连接条件不能限制记录之间的关系时
每一条记录都可以作为自己或者其他记录的叶子
如下所示:
A          1
A          2
A          3
B          3
C          3
B          2
A          3
B          3
C          3
C          2
A          3
B          3
C          3


在这里,我们看到的是
Oracle采用了深度优先的算法

posted @ 2009-09-07 16:29  Mr.Myth  阅读(669)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3