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


    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采用了深度优先的算法

  • 相关阅读:
    【模板小程序】链表排序(qsort/insert_sort/merge_sort)
    链表回文判断(C++)
    【模板小程序】十进制大数除法(输出商和余数)
    【模板小程序】字符串截取
    【模板小程序】翻转一个句子中的单词
    web前端基础背景
    MongoDB基本知识(补充)
    Python-ORM
    Python-元编程
    ElementUI 中 el-table 获取当前选中行的index
  • 原文地址:https://www.cnblogs.com/zeromyth/p/1561948.html
Copyright © 2020-2023  润新知