首页 > 数据库 > Oracle > 关于connet by的学习
关于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)。
参考文档:
如果你读懂了上面的例子,那么就自己分析一下下面这个例子吧。
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/ ,如需转载,请注明出处,否则将追究法律责任。