这里将介绍层次化查询 start with ... connect by prior
语法:
SELECT [LEVEL], column,expression,... FROM table WHERE [WHERE where_cause]
[[START WITH start_condition] [CONNECT BY PRIOR prior_conditon]]
LEVEL:伪列,代表位于树的第几层。对根节点来说,LEVEL返回1,根节点返回2,依次类推。
start_condition:定义层次化的起点。层次化查询必须指定START WITH。
prior_conditon:定义了父行与子行之间的关系。层次化查询必须指定CONNECT BY PRIOR。
CREATE TABLE more_employees (
employee_id INTEGER
CONSTRAINT more_employees_pk PRIMARY KEY,
manager_id INTEGER
CONSTRAINT more_empl_fk_fk_more_empl
REFERENCES more_employees(employee_id),
first_name VARCHAR2(10) NOT NULL,
last_name VARCHAR2(10) NOT NULL,
title VARCHAR2(20),
salary NUMBER(6, 0)
);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 1, NULL, 'James', 'Smith', 'CEO', 800000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 2, 1, 'Ron', 'Johnson', 'Sales Manager', 600000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 3, 2, 'Fred', 'Hobbs', 'Sales Person', 200000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 4, 1, 'Susan', 'Jones', 'Support Manager', 500000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 5, 2, 'Rob', 'Green', 'Sales Person', 40000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 6, 4, 'Jane', 'Brown', 'Support Person', 45000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 7, 4, 'John', 'Grey', 'Support Manager', 30000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 8, 7, 'Jean', 'Blue', 'Support Person', 29000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 9, 6, 'Henry', 'Heyson', 'Support Person', 30000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 10, 1, 'Kevin', 'Black', 'Ops Manager', 100000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 11, 10, 'Keith', 'Long', 'Ops Person', 50000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 12, 10, 'Frank', 'Howard', 'Ops Person', 45000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 13, 10, 'Doreen', 'Penn', 'Ops Person', 47000);
commit ;
1、使用伪列LEVEL
select level,employee_id ,manager_id ,first_name ,last_name
from more_employees
start with employee_id = 1
connect by prior employee_id = manager_id
order by level ;
LEVEL EMPLOYEE_ID MANAGER_ID FIRST_NAME LAST_NAME
------------ ------------ ------------ ---------- ----------
1 1 James Smith
2 10 1 Kevin Black
2 2 1 Ron Johnson
2 4 1 Susan Jones
3 13 10 Doreen Penn
3 7 4 John Grey
3 11 10 Keith Long
3 5 2 Rob Green
3 3 2 Fred Hobbs
3 12 10 Frank Howard
3 6 4 Jane Brown
4 8 7 Jean Blue
4 9 6 Henry Heyson
13 rows selected.
2、格式化层次查询
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with employee_id = 1
connect by prior employee_id = manager_id ;
3、从非根节点开始遍历(start with 限制)
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with last_name = 'Jones'
connect by prior employee_id = manager_id ;
4、在START WITHE子句中使用子查询
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with employee_id =
(select employee_id from more_employees where first_name = 'Kevin' and last_name = 'Black')
connect by prior employee_id = manager_id ;
5、从下往上遍历
可以从某个子节点开始,自下而上进行遍历
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with employee_id = 9
connect by prior manager_id = employee_id ;
6、从层次查询中删除节点和分支
只过滤某些行。用where限制
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
where last_name <> 'Johnson'
start with employee_id = 1
connect by prior employee_id = manager_id ;
过滤父节点下的所有子节点。用connect by prior ... and
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with employee_id = 1
connect by prior employee_id = manager_id and last_name <> 'Johnson' ;
注意:
如果 start with 后面是子节点: connect by prior 后面要是 子节点 = 父节点,则是典型的父子结构 ;connect by prior 后面要是 父节点 = 子节点, 将是 子父结构(倒序)。
如果 start with 后面是父节点:后面要是 子节点 = 父节点,将是正序 ;connect by prior 后面要是 父节点 = 子节点 ,将是 子父结构(倒序),并且数据只有 父节点 和 子节点 2级,其孙子节点及其它的都没有 。
语法:
SELECT [LEVEL], column,expression,... FROM table WHERE [WHERE where_cause]
[[START WITH start_condition] [CONNECT BY PRIOR prior_conditon]]
LEVEL:伪列,代表位于树的第几层。对根节点来说,LEVEL返回1,根节点返回2,依次类推。
start_condition:定义层次化的起点。层次化查询必须指定START WITH。
prior_conditon:定义了父行与子行之间的关系。层次化查询必须指定CONNECT BY PRIOR。
CREATE TABLE more_employees (
employee_id INTEGER
CONSTRAINT more_employees_pk PRIMARY KEY,
manager_id INTEGER
CONSTRAINT more_empl_fk_fk_more_empl
REFERENCES more_employees(employee_id),
first_name VARCHAR2(10) NOT NULL,
last_name VARCHAR2(10) NOT NULL,
title VARCHAR2(20),
salary NUMBER(6, 0)
);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 1, NULL, 'James', 'Smith', 'CEO', 800000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 2, 1, 'Ron', 'Johnson', 'Sales Manager', 600000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 3, 2, 'Fred', 'Hobbs', 'Sales Person', 200000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 4, 1, 'Susan', 'Jones', 'Support Manager', 500000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 5, 2, 'Rob', 'Green', 'Sales Person', 40000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 6, 4, 'Jane', 'Brown', 'Support Person', 45000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 7, 4, 'John', 'Grey', 'Support Manager', 30000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 8, 7, 'Jean', 'Blue', 'Support Person', 29000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 9, 6, 'Henry', 'Heyson', 'Support Person', 30000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 10, 1, 'Kevin', 'Black', 'Ops Manager', 100000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 11, 10, 'Keith', 'Long', 'Ops Person', 50000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 12, 10, 'Frank', 'Howard', 'Ops Person', 45000);
INSERT INTO more_employees ( employee_id, manager_id, first_name, last_name, title, salary) VALUES ( 13, 10, 'Doreen', 'Penn', 'Ops Person', 47000);
commit ;
1、使用伪列LEVEL
select level,employee_id ,manager_id ,first_name ,last_name
from more_employees
start with employee_id = 1
connect by prior employee_id = manager_id
order by level ;
LEVEL EMPLOYEE_ID MANAGER_ID FIRST_NAME LAST_NAME
------------ ------------ ------------ ---------- ----------
1 1 James Smith
2 10 1 Kevin Black
2 2 1 Ron Johnson
2 4 1 Susan Jones
3 13 10 Doreen Penn
3 7 4 John Grey
3 11 10 Keith Long
3 5 2 Rob Green
3 3 2 Fred Hobbs
3 12 10 Frank Howard
3 6 4 Jane Brown
4 8 7 Jean Blue
4 9 6 Henry Heyson
13 rows selected.
2、格式化层次查询
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with employee_id = 1
connect by prior employee_id = manager_id ;
3、从非根节点开始遍历(start with 限制)
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with last_name = 'Jones'
connect by prior employee_id = manager_id ;
4、在START WITHE子句中使用子查询
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with employee_id =
(select employee_id from more_employees where first_name = 'Kevin' and last_name = 'Black')
connect by prior employee_id = manager_id ;
5、从下往上遍历
可以从某个子节点开始,自下而上进行遍历
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with employee_id = 9
connect by prior manager_id = employee_id ;
6、从层次查询中删除节点和分支
只过滤某些行。用where限制
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
where last_name <> 'Johnson'
start with employee_id = 1
connect by prior employee_id = manager_id ;
过滤父节点下的所有子节点。用connect by prior ... and
select level,
lpad(' ',10*level - 10) || first_name || ' ' || last_name,
employee_id ,
manager_id
from more_employees
start with employee_id = 1
connect by prior employee_id = manager_id and last_name <> 'Johnson' ;
注意:
如果 start with 后面是子节点: connect by prior 后面要是 子节点 = 父节点,则是典型的父子结构 ;connect by prior 后面要是 父节点 = 子节点, 将是 子父结构(倒序)。
如果 start with 后面是父节点:后面要是 子节点 = 父节点,将是正序 ;connect by prior 后面要是 父节点 = 子节点 ,将是 子父结构(倒序),并且数据只有 父节点 和 子节点 2级,其孙子节点及其它的都没有 。
发表评论
-
在oracle中通过connect by prior来实现递归查询
2010-08-25 16:22 733connect by 是结构化查询 ... -
Oracle 行转列 万能视图
2010-08-23 10:27 1909之前发过一个帖子,叫行转列的通用过程,http://topic ... -
oracle sql 按日,周,月,年统计
2010-07-29 11:51 2248如: 表:consume_record 字段:consume ... -
EXISTS、IN、NOT EXISTS、NOT IN的区别
2010-07-29 11:50 1067EXISTS、IN、NOT EXISTS、NOT IN的区别: ... -
Oracle的优化器
2010-07-29 11:49 629一、目的: 1、说一说Oracle的Optimizer及其相 ... -
Oracle高效SQL语句原则
2010-07-29 11:48 727良好的SQL语句风格易于发现问题、易于阅读,移植性好。80%的 ...
相关推荐
Oracle数据库中的`CONNECT BY PRIOR`是一个强大的查询构造器,用于处理树形数据结构,尤其在组织层级、部门结构或者员工管理系统中非常常见。这个功能允许我们从一个或多个根节点开始,按照指定的规则遍历整个树结构...
Oracle层次查询的语法包括`START WITH`和`CONNECT BY`两个关键字。`START WITH`指定层次数据的起始节点,即层次结构的根节点。`CONNECT BY`则定义了父节点与子节点之间的关系,用于遍历整个层次结构。此外,可以使用...
- **START WITH**:设置层次查询的起始条件。 - **CONNECT BY PRIOR**:定义父节点和子节点之间的关系。 ##### 示例数据 以EMPLOYEES表为例,假设该表中有如下字段:`empno`(员工编号)、`mgr`(上级编号)、`...
层次化查询还可以通过START WITH子句指定查询的起始节点,以及通过LEVEL伪列获取当前层级的深度。 最后,我们讨论一下“触发器”(Trigger)。触发器是一种数据库对象,它会在特定的数据库操作(如INSERT、UPDATE或...
CONNECT BY子句通常配合START WITH子句使用,其中START WITH指定了递归的起点,而CONNECT BY用于定义父子关系。CONNECT BY子句中的PRIOR关键字用于表示层级之间的连接,它指向前一个步骤得到的列值。例如,如果当前...
FROM emp START WITH empno = 7876 CONNECT BY PRIOR mgr = empno;`将从员工ADAMS开始,向上遍历其上级。 通过这些关键点的运用,可以生成详细的分级报告,同时还可以使用`LPAD`等函数来格式化输出,使得层级结构...
Oracle数据库支持通过`CONNECT BY`和`START WITH`子句实现递归查询。递归查询通常用于处理层次结构数据,如组织结构、文件系统等。 ##### 2. WITH子句 WITH子句是Oracle SQL中的一个特性,它允许用户定义一个临时...
`LEVEL`伪列表示从根节点开始的层级数,`START WITH MGR IS NULL`确保从最高级别的管理者开始查询,而`CONNECT BY PRIOR EMPNO = MGR`定义了父子关系。 #### 四、结果解析 查询结果展示了公司内部的管理层次,每一...
在Oracle数据库中,递归查询主要依赖于`START WITH`和`CONNECT BY PRIOR`两个关键语法。本文将详细介绍这些概念以及具体的使用方法。 #### 二、创建示例表 为了更好地理解Oracle中的递归查询,我们首先需要创建...
在 SELECT 命令中使用 CONNECT BY 和 START WITH 子句可以查询表中的树型结构关系。其命令格式如下: ```sql SELECT 。。。 CONNECT BY {PRIOR 列名 1=列名 2|列名 1=PRIOR 列名 2} [START WITH]; ``` 其中,...
Oracle数据库的分级查询是数据库管理中的一个重要概念,主要用于处理具有层级关系的数据,如组织结构、产品目录等。...通过掌握这些知识,数据库管理员和开发人员能够更有效地管理和查询层次化数据,提升工作效率。
在Oracle中,递归查询主要通过`START WITH`和`CONNECT BY PRIOR`子句实现。 ### 二、递归查询的基本语法 递归查询的基本语法如下: ```sql SELECT column_name(s) FROM table_name START WITH condition CONNECT ...
CONNECT BY PRIOR`子句直接支持递归查询,而SQL Server 2005及以上版本则利用公共表表达式(CTE)的递归调用来实现。POSTgreSQL同样支持CTE子查询进行递归。这些数据库允许在SQL语句中直接对子查询进行递归调用,...
在这个例子中,`START WITH`语句定义了查询的起点,即根节点(ID为1的员工),`CONNECT BY`则指定了层次之间的连接条件(当前员工的ID等于其上级的ID)。 DB2虽然没有直接提供类似Oracle的`CONNECT_BY`功能,但可以...
Oracle 层次化查询是数据库管理系统中用于处理具有层级关系数据的一种强大工具。...通过创建临时字段和使用`START WITH`、`CONNECT BY`语句,我们可以构建一个灵活且高效的查询,方便对数据进行多级分析和操作。
在Oracle中,我们可以使用`CONNECT BY PRIOR`和`START WITH`子句来构建这样的查询。`CONNECT BY PRIOR`用于定义层级关系,`START WITH`则指定了查询的起始节点。 例如,要显示以工作号'002'为根的员工树型结构,...
在自顶向下的遍历中,`CONNECT BY PRIOR column1 = column2`确保当前行的`column1`值等于上一行的`column2`值,反之亦然。例如,`CONNECT BY PRIOR employee_id = manager_id`将根据`employee_id`和`manager_id`的...
2. **查询源树**:使用`START WITH`和`CONNECT BY PRIOR`语句获取源树的所有节点,并将结果存储到`TREE_TABLE`中。 3. **复制节点**: - 为每个节点生成一个新的`ID`。 - 将新生成的`ID`存储到`LOOKUP`表中。 - ...
START WITH parent_id IS NULL CONNECT BY PRIOR id = parent_id; ``` 这将生成一个表示层级关系的路径字符串。 5. **PL/SQL 表达式**: 在PL/SQL块中,可以使用循环和变量来动态地构建字符串。例如,遍历一个...
`START WITH` 定义了查询的起始点,而 `CONNECT BY` 规定了递归关系,`PRIOR` 关键字用来指定当前行与父行的关联。`NOCYCLE` 选项用于防止无限递归,避免循环到已访问过的节点。 在给定的示例中,我们有两个查询...