ITPub博客

首页 > 数据库 > Oracle > 关于connet by的学习

关于connet by的学习

原创 Oracle 作者:czxin788 时间:2015-05-21 21:22:25 0 删除 编辑

关于connet by的学习

 

今天,我学习了oracle 的connect by。搞了半天我才弄明白这个connect by的意思。

         connect by的作用就是递归查询,什么意思呢,下面上实例来理解。

        

 

SQL> select level,ename,job ,ename    from scott.emp emp  start with ename in ('WARD') connect by empno = prior mgr;

 

     LEVEL ENAME                          JOB       ENAME

---------- ------------------------------ --------- ------------------------------

         1 WARD                           SALESMAN  WARD

         2 BLAKE                          MANAGER   BLAKE

         3 KING                           PRESIDENT KING

 

 

解释:

/*START WITH 表示递归的起点,而 CONNECT BY 描述递归步骤,决定了爬树的方向, 也就是如何从第 n 步发展到第 (n + 1) 步。由于在归结 ename  时需要区分第 n 步和第 (n + 1) 步,因此使用 PRIOR (优先的意思)来表明  empno 属于第 n 步,而 mgr 属于第 (n + 1) 步。

先从start with ename=’WARD’这一行数据开始,因为prior 为mgr,那么第一步的mgr就是7698,其对应的empno也必须是7698,这样第二步就会输出7698即blake;7698对应的mgr是7839,所以这个mgr=7839将作为第三步的prior,而empno=7839其实就是king。以此类推。我们看到empno=7839即 king对应的mgr为空,那输出就到此结束。

 

其中的LEVEL是 伪列。这个列的作用是表明产生行的递归步骤 n 属于第几步。 在这个例子中,它表示领导与雇员之间相差的管理等级加 1(因为 LEVEL 一开始为 1)。

 

参考文档:

http://wenku.baidu.com/link?url=yFOQy8ARYvVLikTnD8CfA1OA9f9pwBRyAkNDjusRe3OU5o9ATAgYy2OWX5EcaOR_Q0xWvFLFO4YZgdO4EWTDJ9Oe_aPGMrozb9uLLumIE63

 

 

如果你读懂了上面的例子,那么就自己分析一下下面这个例子吧。

SQL> col ename for a30

SQL> select level,empno,lpad(ename,length(ename)+level*2-2,' ') ename    

  2  from emp

  3  start with ename='KING'

  4  connect by prior empno=mgr;

 

     LEVEL      EMPNO ENAME

---------- ---------- ------------------------------

         1       7839 KING

         2       7566   JONES

         3       7788     SCOTT

         4       7876       ADAMS

         3       7902     FORD

         4       7369       SMITH

         2       7698   BLAKE

         3       7499     ALLEN

         3       7521     WARD

         3       7654     MARTIN

         3       7844     TURNER

 

     LEVEL      EMPNO ENAME

---------- ---------- ------------------------------

         3       7900     JAMES

         2       7782   CLARK

         3       7934     MILLER

 

14 rows selected.

 

 

 

数据具有树状结构,就可以使用分级查询,如上面例子的领导下有员工、一级主管、二级主管、三级主管等 。

 

好了,既然上面两个小例子你都看懂了,那我们在看一下下面这个例子。

需求:输出某个月的所有日期。

解决办法:

select to_date('201504','yyyymm')+(rownum-1)

s_date from dual 

connect by rownum<=last_day(to_date('201504','yyyymm')) - to_date('201504','yyyymm')+1;

 

 

S_DATE

-------------------

2015/04/01 00:00:00

2015/04/02 00:00:00

2015/04/03 00:00:00

2015/04/04 00:00:00

2015/04/05 00:00:00

2015/04/06 00:00:00

2015/04/07 00:00:00

2015/04/08 00:00:00

2015/04/09 00:00:00

2015/04/10 00:00:00

2015/04/11 00:00:00

 

S_DATE

-------------------

2015/04/12 00:00:00

2015/04/13 00:00:00

2015/04/14 00:00:00

2015/04/15 00:00:00

2015/04/16 00:00:00

2015/04/17 00:00:00

2015/04/18 00:00:00

2015/04/19 00:00:00

2015/04/20 00:00:00

2015/04/21 00:00:00

2015/04/22 00:00:00

 

S_DATE

-------------------

2015/04/23 00:00:00

2015/04/24 00:00:00

2015/04/25 00:00:00

2015/04/26 00:00:00

2015/04/27 00:00:00

2015/04/28 00:00:00

2015/04/29 00:00:00

2015/04/30 00:00:00

 

30 rows selected.

 

         看到上面的SQL是不是有点懵?别急,我来一一分解。

         下面这条语句可以输入每个自然月的第一天的日期。

        

 

 

 

 

下面这个SQL可以输出每个自然月的最后一天的日期:

 

 

下面两个SQL就是在输出一个月有多少天。

 

 

 

connect by是关键字,rownum是伪列, connect by rownum就是递归输出数字,因为connect by是会产生递增序列的。

SQL> select rownum from dual connect by rownum <10;

 

    ROWNUM

----------

         1

         2

         3

         4

         5

         6

         7

         8

         9

 

9 rows selected.

 

好了,看了上面的分析,那你就很容易理解下面这条语句的含义了,就不多说了。

select to_date('201504','yyyymm')+(rownum-1)

s_date from dual 

connect by rownum<=last_day(to_date('201504','yyyymm')) - to_date('201504','yyyymm')+1;

 

 

另外,连续输入数字还能这么做:

 

SQL> SELECT LEVEL

  2  FROM dual

  3  CONNECT BY LEVEL < 10;

 

     LEVEL

----------

         1

         2

         3

         4

         5

         6

         7

         8

         9

 

9 rows selected.

 

简单的分页,用level,不能用rownum:

SQL> select level from dual where level between 10 and 20 connect by level<=20;

     LEVEL
----------
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20

11 rows selected

 

SQL> select rownum+10 from dual connect by rownum<11;

 

 ROWNUM+10

----------

        11

        12

        13

        14

        15

        16

        17

        18

        19

        20

 

10 rows selected.

 

 





附件列表

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28916011/viewspace-1666140/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-06-03

  • 博文量
    233
  • 访问量
    858427