sql - 与Oracle CONNECT BY的混淆

标签 sql oracle oracle11g

查询:

select level from dual connect by rownum<10;

给出从1到9的数字。

另一个查询:
SELECT LEVEL FROM DUAL CONNECT BY rownum>5;

输出:1

我在诸如经理/员工的分层数据中使用了CONNECT BY。但是我无法解释以上两个查询的结果。

编辑:
我没有尝试通过query#2实现任何特殊的功能。我只想知道oracle如何解释查询。由于使用CONNECT BY,是否有任何部分充当 parent 和 child ?为什么结果为1?幕后发生了什么?

最佳答案

如何执行和评估CONNECT BY查询-逐步(示例)。

假设我们有下表和按查询连接:

select * from mytable;

         X
----------
         1 
         2 
         3 
         4 

SELECT level, m.* 
FROM mytable m
START with x = 1
CONNECT BY PRIOR x +1 = x  OR  PRIOR x + 2 = x 
ORDER BY level;

步骤1:

从表mytable中选择满足START WITH条件的行,并将LEVEL = 1分配给返回的结果集:
 CREATE TABLE step1 AS
 SELECT 1 "LEVEL", X from mytable
 WHERE x = 1;

 SELECT * FROM step1;

         LEVEL          X
    ---------- ----------
             1          1

步骤2

等级提高1:
LEVEL = LEVEL + 1

使用mytable条件作为连接条件,使用CONNECT BY连接上一步返回的结果集。

在此子句中,PRIOR column-name指的是上一步返回的结果集,而简单的column-name指的是mytable表:
CREATE TABLE step2 AS
SELECT 2 "LEVEL", mytable.X from mytable
JOIN step1 "PRIOR"
ON "PRIOR".x +1 = mytable.x or  "PRIOR".x + 2 = mytable.x;

select * from step2;

     LEVEL          X
---------- ----------
         2          2 
         2          3

STEP x + 1

重复#2,直到最后一个操作返回空结果集。

步骤3
CREATE TABLE step3 AS
SELECT 3 "LEVEL", mytable.X from mytable
JOIN step2 "PRIOR"
ON "PRIOR".x +1 = mytable.x or  "PRIOR".x + 2 = mytable.x;

select * from step3;

     LEVEL          X
---------- ----------
         3          3 
         3          4 
         3          4

步骤4
CREATE TABLE step4 AS
SELECT 4 "LEVEL", mytable.X from mytable
JOIN step3 "PRIOR"
ON "PRIOR".x +1 = mytable.x or  "PRIOR".x + 2 = mytable.x;

select * from step4;

     LEVEL          X
---------- ----------
         4          4 

步骤5
CREATE TABLE step5 AS
SELECT 5 "LEVEL", mytable.X from mytable
JOIN step4 "PRIOR"
ON "PRIOR".x +1 = mytable.x or  "PRIOR".x + 2 = mytable.x;

select * from step5;

no rows selected

第5步未返回任何行,因此现在我们完成查询

最后一步
UNION ALL所有步骤的结果,并将其作为最终结果返回:
SELECT * FROM step1
UNION ALL
SELECT * FROM step2
UNION ALL
SELECT * FROM step3
UNION ALL
SELECT * FROM step4
UNION ALL

SELECT * FROM step5;

     LEVEL          X
---------- ----------
         1          1 
         2          2 
         2          3 
         3          3 
         3          4 
         3          4 
         4          4 

现在,将以上过程应用于您的查询:
SELECT * FROM dual;

DUMMY
-----
X 

SELECT LEVEL FROM DUAL CONNECT BY rownum>5;

步骤1

由于查询不包含START WITH子句,因此Oracle从源表中选择所有记录:
CREATE TABLE step1 AS
SELECT 1 "LEVEL" FROM dual;

select * from step1;

     LEVEL
----------
         1 

步骤2
CREATE TABLE step2 AS
SELECT 2 "LEVEL" from dual
JOIN step1 "PRIOR"
ON rownum > 5

select * from step2;

no rows selected

由于最后一步没有返回任何行,因此我们将完成查询。

最后一步
SELECT * FROM step1
UNION ALL

SELECT * FROM step2;

     LEVEL
----------
         1

最后一个查询的分析:
select level from dual connect by rownum<10;

我留给你做家庭作业。

关于sql - 与Oracle CONNECT BY的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18572701/

相关文章:

mysql - sql对行结果进行排名

mysql - SQL/HiveQL : Is there a way to count the number of JOIN <table> ON <condition> matches per row without a group by?

sql - Where 子句在句法上是正确的,但什么也没给出

mysql - 为什么递归查询比 join 和 group by 更快?

sql - 将确切的一行移到所有行的顶部,留下所有其他的 ASCENDING

c# - Oracle Odp.Net 在调用无效包中的过程时出现未报告的错误

Oracle打包多个 session 的全局变量

sql - 如何根据列值创建重复行

oracle - 确定性函数何时使用先前的计算值?

SQL找地址?