甲骨文,按行数连接
Oracle, Connect By rownum
我试图通过 "engine" 查找有关连接的一些信息。
我发现这个 post:Confusion with Oracle CONNECT BY
用户 krokodilko 回答说:
The analyze of the last query:
select level from dual connect by rownum<10;
I leave to you as a homework assignment.
所以我试着完全按照描述来查询
Select rownum from dual connect by rownum < 3
这是我的 "work":
CREATE TABLE step1 AS
SELECT 1 "LEVEL" FROM dual;
SELECT * FROM step1;
create table step2 as
SELECT 2 "LEVEL" from dual
JOIN step1 "PRIOR" on rownum <=3;
SELECT * FROM step2;
create table step3 as
select 3 "LEVEL" from dual
join step2 "PRIOR" on rownum <=3;
SELECT * FROM step3;
create table step4 as
select 4 "LEVEL" from dual
join step3 "PRIOR" on rownum <=3;
SELECT * FROM step4;
但最后 SELECT 仍然是 returns 行。我误解了什么吗?每次 i Select LEVEL + 1 "LEVEL" 它都有 rownum = 1 所以它总是正确的。那么我是不是失败了?
Krokodilko 的回答中的解释完全错误。你可以忽略 "Correct Answer" 标记和无数的赞成票,它仍然是错误的。有趣的是,他留下了证明解释错误的案例作为练习。
CONNECT BY
查询不起作用 "as if" 每一步都会生成新表(或 SELECT
语句的新输出行集)。这是争论的错误。
相反,总体上(在所有步骤中)只生成了 一个 行集。的确,新行是根据上一步生成的行添加的;但是行集本身是一个,并且还在增长,而不是单独的行集。
这与 ROWNUM
尤其相关。 ROWNUM
分配给单个 "result" 行集中的行,从 1 开始。在 CONNECT BY
查询中,只有一个行集,并且 ROWNUM
从 1 到 n一个递增的序列。
如果 Krokodilko 的答案是正确的,那么 ROWNUM
将在每一步从 1 重新开始。这显然不是这种情况:让我们在 "standard" 分层查询上尝试一下。
select empno, ename, mgr, level, rownum
from scott.emp
start with mgr is null
connect by prior empno = mgr
;
EMPNO ENAME MGR LEVEL ROWNUM
---------- ---------- ---------- ---------- ----------
7839 KING 1 1
7566 JONES 7839 2 2
7788 SCOTT 7566 3 3
7876 ADAMS 7788 4 4
7902 FORD 7566 3 5
7369 SMITH 7902 4 6
7698 BLAKE 7839 2 7
7499 ALLEN 7698 3 8
7521 WARD 7698 3 9
7654 MARTIN 7698 3 10
7844 TURNER 7698 3 11
7900 JAMES 7698 3 12
7782 CLARK 7839 2 13
7934 MILLER 7782 3 14
我试图通过 "engine" 查找有关连接的一些信息。 我发现这个 post:Confusion with Oracle CONNECT BY
用户 krokodilko 回答说:
The analyze of the last query:
select level from dual connect by rownum<10;
I leave to you as a homework assignment.
所以我试着完全按照描述来查询
Select rownum from dual connect by rownum < 3
这是我的 "work":
CREATE TABLE step1 AS
SELECT 1 "LEVEL" FROM dual;
SELECT * FROM step1;
create table step2 as
SELECT 2 "LEVEL" from dual
JOIN step1 "PRIOR" on rownum <=3;
SELECT * FROM step2;
create table step3 as
select 3 "LEVEL" from dual
join step2 "PRIOR" on rownum <=3;
SELECT * FROM step3;
create table step4 as
select 4 "LEVEL" from dual
join step3 "PRIOR" on rownum <=3;
SELECT * FROM step4;
但最后 SELECT 仍然是 returns 行。我误解了什么吗?每次 i Select LEVEL + 1 "LEVEL" 它都有 rownum = 1 所以它总是正确的。那么我是不是失败了?
Krokodilko 的回答中的解释完全错误。你可以忽略 "Correct Answer" 标记和无数的赞成票,它仍然是错误的。有趣的是,他留下了证明解释错误的案例作为练习。
CONNECT BY
查询不起作用 "as if" 每一步都会生成新表(或 SELECT
语句的新输出行集)。这是争论的错误。
相反,总体上(在所有步骤中)只生成了 一个 行集。的确,新行是根据上一步生成的行添加的;但是行集本身是一个,并且还在增长,而不是单独的行集。
这与 ROWNUM
尤其相关。 ROWNUM
分配给单个 "result" 行集中的行,从 1 开始。在 CONNECT BY
查询中,只有一个行集,并且 ROWNUM
从 1 到 n一个递增的序列。
如果 Krokodilko 的答案是正确的,那么 ROWNUM
将在每一步从 1 重新开始。这显然不是这种情况:让我们在 "standard" 分层查询上尝试一下。
select empno, ename, mgr, level, rownum
from scott.emp
start with mgr is null
connect by prior empno = mgr
;
EMPNO ENAME MGR LEVEL ROWNUM
---------- ---------- ---------- ---------- ----------
7839 KING 1 1
7566 JONES 7839 2 2
7788 SCOTT 7566 3 3
7876 ADAMS 7788 4 4
7902 FORD 7566 3 5
7369 SMITH 7902 4 6
7698 BLAKE 7839 2 7
7499 ALLEN 7698 3 8
7521 WARD 7698 3 9
7654 MARTIN 7698 3 10
7844 TURNER 7698 3 11
7900 JAMES 7698 3 12
7782 CLARK 7839 2 13
7934 MILLER 7782 3 14