随笔-42  评论-12  文章-0  trackbacks-0

如果打算列出所有的员工和他的经理。可以完成一个自外连接,如下:

SELECT e_top.lname, e_2.lname, e_3.lname, e_4.lname 
            FROM employee e_top LEFT OUTER JOIN employee e_2 
                                                ON e_top.emp_id = e_2.manager_emp_id
                                LEFT OUTER JOIN employee e_3 
                                                ON e_2.emp_id = e_3.manager_emp_id
                                LEFT OUTER JOIN employee e_4 
                                                ON e_3.emp_id = e_4.manager_emp_id
            WHERE e_top.manager_emp_id IS NULL;
            LNAME                LNAME                LNAME                LNAME
            -------------------- -------------------- -------------------- ------
            KING                 JONES                FORD                 SMITH
            KING                 JONES                SCOTT                ADAMS
            KING                 BLAKE                TURNER
            KING                 BLAKE                ALLEN
            KING                 BLAKE                WARD
            KING                 CLARK                MILLER
            KING                 BLAKE                MARTIN
            KING                 BLAKE                JAMES
            8 rows selected.

这种类型的查询有缺点。第一,需要知道组织结构有多少层,而且,对于一个有四层的employee表,你需要把四个表实例连接在一起,考虑一下如果表中有20层的情况。

为了解决这些问题,oracle提供了对于ANSI SQL的一些扩展。

START WITH ... CONNECT BY 子句

PRIOR操作符

LEVEL伪列

语法如下:

[[START WITH condition1]  CONNECT BY condition2]
START WITH condition1 指定根元素。所有满足condition1 条件的行都被认作是根。
condition1 可以包含子查询。
CONNECT BY condition2 指定父行与子行的关系。condition2必须包含一个PRIOR
操作符,用来确定父行里的列,condition2不能包含子查询。
SELECT lname, emp_id, manager_emp_id
            FROM employee
            START WITH manager_emp_id IS NULL
            CONNECT BY PRIOR emp_id = manager_emp_id;
            LNAME                    EMP_ID MANAGER_EMP_ID
            -------------------- ---------- --------------
            KING                       7839
            JONES                      7566           7839
            SCOTT                      7788           7566
            ADAMS                      7876           7788
            FORD                       7902           7566
            SMITH                      7369           7902
            BLAKE                      7698           7839
            ALLEN                      7499           7698
            WARD                       7521           7698
            MARTIN                     7654           7698
            TURNER                     7844           7698
            JAMES                      7900           7698
            CLARK                      7782           7839
            MILLER                     7934           7782
            14 rows selected.

考虑如下查询,以一个工作时间最长的员工为根:

SELECT lname, emp_id, manager_emp_id
            FROM employee
            START WITH hire_date = (SELECT MIN(hire_date) FROM employee)
            CONNECT BY manager_emp_id = PRIOR emp_id;
            LNAME                    EMP_ID MANAGER_EMP_ID
            -------------------- ---------- --------------
            BLAKE                      7698           7839
            ALLEN                      7499           7698
            WARD                       7521           7698
            MARTIN                     7654           7698
            TURNER                     7844           7698
            JAMES                      7900           7698
            6 rows selected.
posted on 2007-10-11 17:47 tianjuchuan 阅读(215) 评论(0)  编辑 收藏 引用 所属分类: sql
只有注册用户登录后才能发表评论。