`

SQL层次化查询START BY ... CONNECT BY PRIOR(原创)

 
阅读更多

概述

层次化查询,即树型结构查询,是SQL中经常用到的功能之一,通常由根节点,父节点,子节点,叶节点组成,其语法如下:
SELECT [LEVEL] ,column,expression,...
FROM table_name
[WHERE where_clause]
[[START WITH start_condition] [CONNECT BY PRIOR prior_condition]];
LEVEL:伪列,用于表示树的层次
start_condition:层次化查询的起始条件,指定阶层的根。
prior_condition:定义父节点和子节点之间的关系,PRIOR指定父节点。作为运算符,PRIOR和加(+)减(-)运算的优先级相同。condition ... PRIOR expr = expr 或者 ... expr = PRIOR expr

例:
CONNECT BY last_name != 'King' AND PRIOR employee_id = manager_id ...
CONNECT BY PRIOR employee_id = manager_id and PRIOR account_mgr_id = customer_id SYS_CONNECT_BY_PATH

SYS_CONNECT_BY_PATH这个函数是oracle9i才新提出来的!它一定要和connect by子句合用!第一个参数是形成树形式的字段,第二个参数是父级和其子级分隔显示用的分隔符!

示例

SQL>  select empno,mgr,ename,job,level from emp
  2  start with empno = 7839
  3* connect by prior empno = mgr
     EMPNO        MGR ENAME    JOB             LEVEL
---------- ---------- -------- ---------- ----------
      7839            KING     PRESIDENT           1
      7566       7839 JONES    MANAGER             2
      7788       7566 SCOTT    ANALYST             3
      7876       7788 ADAMS    CLERK               4
      7902       7566 FORD     ANALYST             3
      7369       7902 SMITH    CLERK               4
      7698       7839 BLAKE    MANAGER             2
      7499       7698 ALLEN    SALESMAN            3
      7521       7698 WARD     SALESMAN            3
      7654       7698 MARTIN   SALESMAN            3
      7844       7698 TURNER   SALESMAN            3
     EMPNO        MGR ENAME    JOB             LEVEL
---------- ---------- -------- ---------- ----------
      7900       7698 JAMES    CLERK               3
      7782       7839 CLARK    MANAGER             2
      7934       7782 MILLER   CLERK               3
SQL>
select empno,max(sys_connect_by_path(ename,',')) a from emp
  2  start with empno=7839
  3  connect by prior empno=mgr
  4* group by empno

     EMPNO A
---------- ------------------------------
      7839 ,KING
      7844 ,KING,BLAKE,TURNER
      7782 ,KING,CLARK
      7698 ,KING,BLAKE
      7902 ,KING,JONES,FORD
      7521 ,KING,BLAKE,WARD
      7566 ,KING,JONES
      7788 ,KING,JONES,SCOTT
      7654 ,KING,BLAKE,MARTIN
      7934 ,KING,CLARK,MILLER
      7499 ,KING,BLAKE,ALLEN
     EMPNO A
---------- ------------------------------
      7876 ,KING,JONES,SCOTT,ADAMS
      7369 ,KING,JONES,FORD,SMITH
      7900 ,KING,BLAKE,JAMES
14 rows selected.

树型结构遍历过程(通过上面的查询来描述)
1).从根节点开始(即where_clause中的条件,如果为非根节点则分根节点作为根节点开始遍历,如上例empno = 7839)
2).遍历根节点(得到empno = 7839记录的相关信息)
3).判断该节点是否存在子节点,如果有则访问最左侧未被访问的子节点,否则下一步。上例中prior_condition为empno = mgr,表示子节点的mgr等于父节点的empno,即下一条返回记录的mgr应当等于前一条记录的empno
4).当节点为叶节点,则访问完毕。

5).返回到该节点的父节点,直至检索完所有数据

 

=========================================================

格式化层次查询结果,使用2* level - 2个“_”向左填充。修改start with 中的条件,从非根节点开始遍历
SQL>  select ename,level,lpad(ename,length(ename)+(level*2-2),'_') as Ename ,job
  2  from emp
  3  start with ename='JONES'
  4* connect by prior empno = mgr

ENAME                LEVEL ENAME           JOB
--------------- ---------- --------------- ----------
JONES                    1 JONES           MANAGER
SCOTT                    2 __SCOTT         ANALYST
ADAMS                    3 ____ADAMS       CLERK
FORD                     2 __FORD          ANALYST
SMITH                    3 ____SMITH       CLERK

也可以从下向上进行遍历
SQL> select ename,level,lpad(ename,length(ename)+(level*2-2),'_') as Ename ,job
  2  from emp
  3  start with ename='SCOTT'
  4* connect by prior mgr = empno
ENAME                LEVEL ENAME           JOB
--------------- ---------- --------------- ----------
SCOTT                    1 SCOTT           ANALYST
JONES                    2 __JONES         MANAGER
KING                     3 ____KING        PRESIDENT
============================================================
在层次查询中删除节点和分支

通过where子句来过滤SCOTT用户,但SCOTT的下属ADAMS并没有过滤掉
SQL> select ename,level,lpad(ename,length(ename)+(level*2-2),'_') as Ename ,job
  2  from emp
  3  where ename != 'SCOTT'
  4  start with ename='JONES'
  5* connect by prior empno = mgr
ENAME                LEVEL ENAME           JOB
--------------- ---------- --------------- ----------
JONES                    1 JONES           MANAGER
ADAMS                    3 ____ADAMS       CLERK
FORD                     2 __FORD          ANALYST
SMITH                    3 ____SMITH       CLERK

通过将过滤条件由where 子句的内容移动到connect by prior 子句中过滤掉SCOTT及其下属
SQL>
select ename,level,lpad(ename,length(ename)+(level*2-2),'_') as Ename ,job
  2  from emp
  3  start with ename='JONES'
  4* connect by prior empno = mgr and ename != 'SCOTT'

ENAME                LEVEL ENAME           JOB
--------------- ---------- --------------- ----------
JONES                    1 JONES           MANAGER
FORD                     2 __FORD          ANALYST
SMITH                    3 ____SMITH       CLERK

配合条件查询
SQL>
select ename,sal,level,lpad(ename,length(ename)+(level*2-2),'_') as Ename ,job
  2  from emp
  3  --where sal > 1500
  4  start with ename='KING'
  5* connect by prior empno = mgr and sal > (select avg(sal) from emp)

ENAME                  SAL      LEVEL ENAME           JOB
--------------- ---------- ---------- --------------- ----------
KING                  5000          1 KING            PRESIDENT
JONES                 2975          2 __JONES         MANAGER
SCOTT                 3000          3 ____SCOTT       ANALYST
FORD                  3000          3 ____FORD        ANALYST
BLAKE                 2850          2 __BLAKE         MANAGER
CLARK                 2450          2 __CLARK         MANAGER

 

参考至:http://blog.csdn.net/robinson_0612/article/details/5616877
                  http://www.51cto.com/art/200705/47640_1.htm
                  http://myiteyeverywell-163-com.iteye.com/blog/1471752

                  http://www.itpub.net/thread-620427-1-1.html

                  http://blog.chinaunix.net/uid-3634-id-2129988.html

                  http://blog.sina.com.cn/s/blog_777a9ccb0101740d.html
                  http://www.cnblogs.com/huanghai223/archive/2010/12/10/1902696.html

本文原创,转载请注明出处、作者

如有错误,欢迎指正
邮箱:czmcj@163.com

0
0
分享到:
评论

相关推荐

    oracle中connect-by-prior用法,实战解决日期分解问题.docx

    在SQL查询中,`CONNECT BY PRIOR`的语法结构如下: ```sql SELECT ... FROM tablename START WITH condition_1 CONNECT BY PRIOR condition_2 WHERE condition_3; ``` 1. `START WITH`子句定义了树结构的起点,也...

    Oracle 实战SQL层次查询

    ### Oracle 实战SQL层次查询详解 #### 一、层次查询概念 层次查询,也被称为树型结构查询,是在SQL中最常见的功能之一。这种查询方式主要用于处理具有层级结构的数据,例如组织架构、产品分类等场景。在Oracle...

    Oracle层次查询功能的剖析.pdf

    Oracle层次查询的语法包括`START WITH`和`CONNECT BY`两个关键字。`START WITH`指定层次数据的起始节点,即层次结构的根节点。`CONNECT BY`则定义了父节点与子节点之间的关系,用于遍历整个层次结构。此外,可以使用...

    数据库开发 Oracle数据库 SQL开发教程 第10章 层次查询(共17页).pdf

    在学习层次查询时,首先要理解自然树结构的概念,这通常指的是数据表中的一行数据可以有多个子行,而每个子行又有自己的子级,形成一个层次化的结构。例如,EMP表中的数据就展示了员工的上级-下级关系,形成了一个...

    一种MySQL数据库SQL递归查询的研究与实现.pdf

    CONNECT BY PRIOR`子句直接支持递归查询,而SQL Server 2005及以上版本则利用公共表表达式(CTE)的递归调用来实现。POSTgreSQL同样支持CTE子查询进行递归。这些数据库允许在SQL语句中直接对子查询进行递归调用,...

    Oracle+SQL精妙SQL语句讲解.txt

    CONNECT BY PRIOR RN = RN - 1 AND PRIOR ID = ID GROUP BY ID, NAME ORDER BY ID; ``` 此查询首先根据`TABLE1.ID`对数据进行分组,并按`NAME`排序,然后使用`ROW_NUMBER()`函数为每一组分配一个行号。之后使用`SYS...

    oracle 的包,层次化查询和触发器视频教程

    Oracle提供了CONNECT BY子句,配合PRIOR关键字,用于构建查询树形结构数据的SQL语句。例如,你可以用它来查询公司的组织架构,找出每个员工的直接上级。层次化查询还可以通过START WITH子句指定查询的起始节点,以及...

    在ORACLE、MSSQL、MYSQL中树结构表递归查询的实现.pdf

    CONNECT BY子句通常配合START WITH子句使用,其中START WITH指定了递归的起点,而CONNECT BY用于定义父子关系。CONNECT BY子句中的PRIOR关键字用于表示层级之间的连接,它指向前一个步骤得到的列值。例如,如果当前...

    SQL语句 递归

    在Oracle中,递归查询主要通过`START WITH`和`CONNECT BY PRIOR`子句实现。 ### 二、递归查询的基本语法 递归查询的基本语法如下: ```sql SELECT column_name(s) FROM table_name START WITH condition CONNECT ...

    oracle层次查询

    `LEVEL`伪列表示从根节点开始的层级数,`START WITH MGR IS NULL`确保从最高级别的管理者开始查询,而`CONNECT BY PRIOR EMPNO = MGR`定义了父子关系。 #### 四、结果解析 查询结果展示了公司内部的管理层次,每一...

    oracle prior

    在 SELECT 命令中使用 CONNECT BY 和 START WITH 子句可以查询表中的树型结构关系。其命令格式如下: ```sql SELECT 。。。 CONNECT BY {PRIOR 列名 1=列名 2|列名 1=PRIOR 列名 2} [START WITH]; ``` 其中,...

    Oracle递归查询

    在Oracle数据库中,递归查询主要依赖于`START WITH`和`CONNECT BY PRIOR`两个关键语法。本文将详细介绍这些概念以及具体的使用方法。 #### 二、创建示例表 为了更好地理解Oracle中的递归查询,我们首先需要创建...

    高性能sql調整,適用oracle和系統開發人員學習

    在Oracle中,我们可以使用`CONNECT BY PRIOR`和`START WITH`子句来构建这样的查询。`CONNECT BY PRIOR`用于定义层级关系,`START WITH`则指定了查询的起始节点。 例如,要显示以工作号'002'为根的员工树型结构,...

    00571 Oracle公司内部数据库培训资料-Les19_分级查询(PPT 16页).ppt

    Oracle数据库的分级查询是数据库管理中的一个重要概念,主要用于处理具有层级关系的数据,如组织结构、产品目录等。...通过掌握这些知识,数据库管理员和开发人员能够更有效地管理和查询层次化数据,提升工作效率。

    ORACLE与SQLSERVER语法差异分析

    - 对于ORACLE,递归查询同样使用`WITH`子句和`CONNECT BY`关键字,但`PRIOR`关键字的位置不同,用来指定层次关系的方向。`START WITH`指定了递归开始的条件。 2. **行号**: - ORACLE使用`ROWNUM`来获取行号,它...

    oracle 层次化查询(行政区划三级级联)

    Oracle 层次化查询是数据库管理系统中用于处理具有层级关系数据的一种强大工具。在这个特定的案例中,我们看到的是一个行政区划数据表,其中包含了中国的省份、城市和县的编码。行政区划代码的设计使得通过检查特定...

    在db2和oracle中的对树的递归查询语句

    在数据存储中,树形结构是一种层次化的数据模型,它由节点(或称为记录)组成,每个节点可以有零个或多个子节点,这种结构通常用于表示组织关系、文件系统或层级分类等。 在Oracle中,对树的递归查询主要依赖于`...

    工作中常用的sql--------------------------

    CONNECT BY PRIOR col5 = col6 GROUP BY col1, col2, col3; ``` **解析**: 这是一个复杂的查询示例,利用了窗口函数、字符串函数、树状遍历等功能。具体步骤如下: 1. 使用`RANK()`函数对每一组`col1`, `col2`, `...

    10.2.0.3版本 with改造递归查询

    Oracle数据库支持通过`CONNECT BY`和`START WITH`子句实现递归查询。递归查询通常用于处理层次结构数据,如组织结构、文件系统等。 ##### 2. WITH子句 WITH子句是Oracle SQL中的一个特性,它允许用户定义一个临时...

    oracle数据库ppt中科院培训专用Lescn7PPT优秀资料.ppt

    在自顶向下的遍历中,`CONNECT BY PRIOR column1 = column2`确保当前行的`column1`值等于上一行的`column2`值,反之亦然。例如,`CONNECT BY PRIOR employee_id = manager_id`将根据`employee_id`和`manager_id`的...

Global site tag (gtag.js) - Google Analytics