Sql Oracle,通过rownum连接
我试图找到一些关于“引擎连接”的信息。 我发现这个帖子: 用户krokodilko回答说:Sql Oracle,通过rownum连接,sql,oracle,hierarchical,connect-by,Sql,Oracle,Hierarchical,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. 上次查询的分析: rownum从dual connect中选择levelKrokodilko回答中的解释完全错误。你可以忽略“正确答案”标记和无数的投票,这仍然是错
The analyze of the last query:
select level from dual connect by rownum<10;
I leave to you as a homework assignment.
上次查询的分析:
rownum从dual connect中选择levelKrokodilko回答中的解释完全错误。你可以忽略“正确答案”标记和无数的投票,这仍然是错误的。有趣的是,他把证明解释错误的案例作为练习离开了
connectby
查询在每一步都“好像”生成新表(或SELECT
语句的新输出行集)。这是论点中的错误
相反,整个(所有步骤)只生成一个行集。的确,在上一步生成的行的基础上添加了新行;但行集本身是一个不断增长的行集,而不是单独的行集
这与ROWNUM
特别相关ROWNUM
分配给单个“结果”行集中的行,从1开始。在connectby
查询中,只有一个行集,ROWNUM
按递增顺序从1变为n
如果Krokodilko的答案是正确的,那么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
使用递归CTE(公共表表达式)遍历图形和层次结构,而不是[几乎过时的]connectby
。它是SQL标准的一部分,不同于connectby
@theimpler-您的评论有几个地方不对劲。首先,分层的connectby
查询和递归的CTE查询的工作方式不同:connectby
在单个行上工作,而递归的CTE在集合上工作。这有多种含义,特别是对周期的定义和行为。其次,connectby
比递归查询快得多(递归查询的成本要灵活得多),因此,当确实存在connectby
解决方案时,它可能是首选。第三,connectby
提供CONNECT\u BY\u ISLEAF
;可以在递归CTE中克隆,但不容易。@mathguy我喜欢被纠正:D我会读的。谢谢
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 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