表结构如下:
id    val
1     aa
2     bb查询语句及结果如下:
  SELECT id, level,val
        FROM tab
     CONNECT BY  LEVEL<=31 1 AA
1 2 AA
1 3 AA
2 3 BB
2 2 BB
1 3 AA
2 3 BB
2 1 BB
1 2 AA
1 3 AA
2 3 BB
2 2 BB
1 3 AA
2 3 BB
的出十四条记录
我想知道,Oracle是怎么处理的得出了14条记录
网上搜过其他的解释,说是没层level产生后与原数据进行笛卡尔积运算
但是我算了一下,按笛卡尔积算应该有12条,即:2*1+2*2+2*3=12
求解释,谢谢大家了。

解决方案 »

  1.   

    就是一棵完整二叉树,应该是
    2的一次方+2的二次方+2的三次方=14       aa               bb
        aa      bb       aa      bb
      aa  bb  aa   bb  aa  bb  aa  bb
      

  2.   

    能描述一下,Oracle是如何处理数据的吗?
      

  3.   

    对于一条记录,生成的结果集合应该是2的level次幂-1对于例子中的,生成的结果结合是2的3次幂-1+2的3次幂-1=14 
      

  4.   

    简单的讲就是,每一层的结果集都是基数记录与上一层的笛卡尔积。
    例如
    Level 1
    aa     bb
    level 2
    即为aa  bb与 aa  bb的笛卡尔积
    即aa  bb  aa   bb
    Level 3
    即为aa  bb  aa   bb与aa  bb  aa   bb的笛卡尔积
    即aa  bb  aa   bb  aa  bb  aa   bb
      

  5.   

    假如把表中的数据换成这样
    id   val
    2    aa
    4    bb
    查询语句如下:
    SELECT id, level,val
            FROM tab
         CONNECT BY  LEVEL<=id
    得到的结果如下:
    2 1 aa
    2 2 aa
    4 3 bb
    4 4 bb
    4 2 bb
    4 3 bb
    4 4 bb
    4 1 bb
    2 2 aa
    4 3 bb
    4 4 bb
    4 2 bb
    4 3 bb
    4 4 bb
    14 rows selected
    这个结果应该要如何解释啊?谢谢了
      

  6.   

    应当是这样,前两层是完全二叉树,但是第二层之后,叶子就只有一个bb了,即二层之后为bb与上一层的笛卡尔积..
    aa  bb
    aa bb aa bb
    bb bb bb bb
    bb bb bb bb
      

  7.   

    笛卡尔积不应该是集合A=(AA,BB),集合B=(AA,BB)
    得到的是(AA,AA)(BB,BB)(AA,BB)(BB,AA)
    AA BB和AA BB的笛卡尔积怎么会是AA,BB,AA,BB呢?
    有点儿糊涂
      

  8.   

    connect by是以树状的形式来展现的  为何会得出14条数据呢 LZ可以看下这例子 然后将层次也列出来了 容易理解一点这是层次为3的时候  如果 为level<=4 那么将会展开出第四层  类型差不多with x as
        (select 'aa' chr from dual
        union all
        select 'bb' chr from dual)
        select level,chr,lpad(' ',(level-1)*5,'-')||chr other from x connect by level<=3;
     
        LEVEL CHR    OTHER
        ----- ------ ----------------------
        1     aa     aa
        2     aa     ---- aa
        3     aa     --------- aa
        3     bb     --------- bb
        2     bb     ---- bb
        3     aa     --------- aa
        3     bb     --------- bb
        1     bb     bb
        2     aa     ---- aa
        3     aa     --------- aa
        3     bb     --------- bb
        2     bb     ---- bb
        3     aa     --------- aa
        3     bb     --------- bb
      

  9.   

    还想请教一个问题,也是关于connect  by 的。
    id val
    2 aa
    4 bb
    查询出与id值相同条数的该数据:
    插叙语句如下:SELECT level,id,val
            FROM tab
         CONNECT BY  LEVEL<=id and 
         prior id=id and prior dbms_random.value is not null
    查询结果如下:
    1 2 aa
    2 2 aa
    1 4 bb
    2 4 bb
    3 4 bb
    4 4 bb
    这个结果是怎么的到的
    语句中的prior id=id
    和dbms_random.value is not null是和用法?
      

  10.   

    你能理解CONNECT BY吧?它相当于是一个递归的自连接,不断地把每层的连接结果叠加到结果集中。两层之间的连接条件和递归出口写在CONNECT BY中。在这里数据并无父子关系,只是要让同一行数据重复出现,因此我们的连接的条件只用到了表的主键id=PRIOR id, 此外再用LEVEL控制层数作为递归出口。但ORACLE有个检查,如果你有前后连接条件(id=PRIOR id),当同一行数据再次出现,它就会报一个错:
    ERROR:
    ORA-01436: CONNECT BY loop in user data
    为了欺骗它,这里用了一个PRIOR DBMS_RANDOM.VALUE(相当于获取随机数), 因为DBMS_RANDOM.VALUE每次调用都返回不同结果,所以它认为两行数据不一样,所以不报错了。
    所以 LZ上面这个例子  结果就是根据id来的  因为层次level<=id 而且prior id=id和DBMS_RANDOM.VALUE会过滤多余的数据  所以显示的时候  你的id值是多少 当前id的行数就会显示多少