Oracle, Connect By rownum

自作多情 提交于 2019-12-11 13:50:43

问题


I tried to find some informations about connect by "engine". I found this post: Confusion with Oracle CONNECT BY

User krokodilko answered and says:

The analyze of the last query:

select level from dual connect by rownum<10;
I leave to you as a homework assignment.

So i tried to do exactly as described to query

Select rownum from dual connect by rownum < 3

And here's my "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;

But last SELECT still returns rows. Am I misunderstood something? Every time i Select LEVEL + 1 "LEVEL" it has rownum = 1 so it's always true. So am i failed steps?


回答1:


The explanation in Krokodilko's answer is simply wrong. You may disregard the "Correct Answer" mark and the numerous upvotes, it's still wrong. It is interesting that he left as an exercise exactly the case that proves the explanation is wrong.

A CONNECT BY query doesn't work "as if" new tables (or new output rowsets of SELECT statements, anyway) are generated at each step. This is the mistake in the argument.

Rather, there is only one rowset generated overall (across all steps). It is true that new rows are added based on the rows generated at the previous step; but the rowset itself is one, and growing, not separate rowsets.

This is particularly relevant with regard to ROWNUM. ROWNUM is assigned to rows in a single "result" rowset, starting with 1. In a CONNECT BY query, there is only one rowset, and ROWNUM goes from 1 to n in an increasing sequence.

If Krokodilko's answer were correct, then ROWNUM would restart at 1 at each step. This is clearly not the case: let's try it on a "standard" hierarchical query.

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


来源:https://stackoverflow.com/questions/52899897/oracle-connect-by-rownum

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!