一尘不染

为什么表上的CONNECT BY LEVEL返回多余的行?

sql

在表上执行时,使用CONNECT BY LEVEL似乎返回太多行。发生什么背后的逻辑是什么?

假设下表:

create table a ( id number );

insert into a values (1);
insert into a values (2);
insert into a values (3);

该查询返回12行(SQL Fiddle)。

 select id, level as lvl
   from a
connect by level <= 2
  order by id, level

表A中列LVL的值为1的每一行,表A中列LVL为2的表A的每一行三,即:

ID | 轻型装甲车
--- + -----
 1 | 1个
 1 | 2个
 1 | 2个
 1 | 2个
 2 | 1个
 2 | 2个
 2 | 2个
 2 | 2个
 3 | 1个
 3 | 2个
 3 | 2个
 3 | 2个

它等效于此查询,它返回相同的结果。

 select id, level as lvl
   from dual
  cross join a
connect by level <= 2
  order by id, level

我不明白为什么这些查询返回12行,或者为什么对于ID列的每个值只有三行LVL为2,而只有三行LVL为1。

对于每个ID值,将“连接”的级别数增加到3会返回13行。LVL为1时为1,LVL为2时为3,LVL为3时为9,这似乎表明返回的行是表A中的行数乘以LVL值减1的幂。

我本来希望这些查询与以下查询相同,该查询返回6行

select id, lvl
  from ( select level  as lvl
           from dual
        connect by level  <= 2
                )
 cross join a
 order by id, lvl

对我来说,该文档在解释应该发生什么方面不是特别清楚。这些权力正在发生什么,为什么前两个查询与第三个查询不同?


阅读 108

收藏
2021-03-17

共1个答案

一尘不染

在第一个查询中,您仅按级别进行连接。因此,如果级别<= 1,则每次获得1条记录。如果级别<= 2,则每个级别1次(对于级别1)+
N次(其中N是表中的记录数)。就像您正在交叉联接一样,因为您只是从表中选择所有记录,直到达到级别为止,而没有其他条件来限制结果。对于级别<=
3,将对每个结果再次进行此操作。

因此,对于3条记录:

  • Lvl 1:3记录(全部具有1级)
  • Lvl 2:3记录的级别为1 + 3 * 3记录的级别为2 = 12
  • Lvl 3:3 + 3 * 3 + 3 * 3 * 3 = 39(实际上,每个记录13条)。
  • Lvl 4:开始看到图案吗?:)

这并不是真正的交叉连接。交叉联接将仅返回此查询结果中具有级别2的记录,而通过此连接,您将获得具有级别1的记录以及具有级别2的记录,因此结果为3 + 3 * 3,而不仅仅是3 * 3记录。

2021-03-17