Oracle, Connect By rownum

Я попытался найти информацию о подключении «движком». Я нашел этот пост: Путаница с 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

И вот моя «работа»:

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 по-прежнему возвращает строки. Я что-то неправильно понял? Каждый раз, когда я выбираю LEVEL + 1 «LEVEL», он имеет rownum = 1, поэтому он всегда прав. Так что я не сделал шагов?

Всего 1 ответ


Объяснение в ответе Крокодилко просто неверно. Вы можете не обращать внимания на знак «Правильный ответ» и многочисленные перевернутые знаки, это все еще неправильно. Интересно, что он оставил в качестве упражнения именно тот случай, который доказывает, что объяснение неверно.

Запрос CONNECT BY не работает «как если бы» на каждом шаге генерируются новые таблицы (или новые выходные ряды SELECT ). Это ошибка в аргументе.

Скорее всего, генерируется только один набор строк (на всех этапах). Верно, что новые строки добавляются на основе строк, сгенерированных на предыдущем шаге; но сам набор строк является одним и растет, а не отдельные ряды.

Это особенно актуально в отношении ROWNUM . ROWNUM присваивается строкам в одном ROWNUM строк «результат», начиная с 1. В запросе CONNECT BY имеется только один набор строк, а ROWNUM от 1 до n в возрастающей последовательности.

Если бы ответ Крокодилко был правильным, то ROWNUM возобновил бы 1 на каждом шаге. Это явно не так: давайте попробуем его по «стандартным» иерархическим запросам.

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

Есть идеи?

10000