oracle connect_by_iscycle,Oracle用Start with...Connect By子句递归查询

Basic Syntax Elements

START WITH CONNECT BY

[NOCYCLE]

CONNECT BY PRIOR

A condition that identifies the relationship between parent rows and child rows of the hierarchy

CONNECT BY =

conn hr/hr

SELECT employee_id, last_name, manager_id

FROM employees

CONNECT BY PRIOR employee_id = manager_id;

START WITH

Specifies a condition that identifies the row(s) to be used as the root(s) of a hierarchical query

START WITH (column_name) =

SELECT last_name, employee_id, manager_id, LEVEL

FROM employees

START WITH employee_id = 100

CONNECT BY PRIOR employee_id = manager_id;

ORDER SIBLINGS BY

SIBLINGS BY preserves any ordering specified in the hierarchical query clause and then applies the order_by_clause to the siblings of the hierarchy

ORDER SIBLINGS BY (column_name)

SELECT last_name, employee_id, manager_id, LEVEL

FROM employees

START WITH employee_id = 100

CONNECT BY PRIOR employee_id = manager_id

ORDER SIBLINGS BY last_name;

CONNECT_BY_ROOT

CONNECT_BY_ROOT is a unary operator that is valid only in hierarchical queries. When you qualify a column with this operator, Oracle returns the column value using data from the root row.

Cannot be specified with the START WITH or  CONNECT BY condition.

The following example returns the last name of each employee in department 110, each manager above that employee in the hierarchy, the number of levels between manager and employee, and the path between the two:

col emp format a20

col mgr format a20

set linesize 120SELECT "Name", SUM(salary) "Total_Salary"

FROM (

SELECT CONNECT_BY_ROOT last_name "Name", salary

FROM employees

WHERE department_id = 110

CONNECT BY PRIOR employee_id = manager_id)

GROUP BY "Name";

-- Thanks Colin for the correction

CONNECT_BY_ISCYCLE Pseudocolumn

The CONNECT_BY_ISCYCLE pseudocolumn returns 1 if the current row has a child which is also its ancestor. Otherwise it returns 0

UPDATE employees SET manager_id = 145

WHERE employee_id = 100;

SELECT last_name, LEVEL, SYS_CONNECT_BY_PATH(last_name, '/') "Path"

FROM employees

WHERE LEVEL <= 3 AND department_id = 80

START WITH last_name = 'King'

CONNECT BY PRIOR employee_id = manager_id AND LEVEL <= 4;

2 3 4 5 6 7 ERROR:

ORA-01436: CONNECT BY loop in user data

SELECT last_name, CONNECT_BY_ISCYCLE "Cycle", LEVEL, SYS_CONNECT_BY_PATH(last_name, '/') "Path"

FROM employees

WHERE LEVEL <= 3 AND department_id = 80

START WITH last_name = 'King'

CONNECT BY NOCYCLE PRIOR employee_id = manager_id

AND LEVEL <= 4;

CONNECT_BY_ISLEAF Pseudocolumn

The CONNECT_BY_ISLEAF pseudocolumn returns 1 if the current row is a leaf of the tree defined by the CONNECT BY condition. Otherwise it returns 0. This information indicates whether a given row can be further expanded to show more of the hierarchy.

SELECT last_name "Employee", CONNECT_BY_ISLEAF "IsLeaf",

LEVEL, SYS_CONNECT_BY_PATH(last_name, '/') "Path"

FROM employees

WHERE level <= 3

AND department_id = 80

START WITH last_name = 'King'

CONNECT BY PRIOR employee_id = manager_id

AND LEVEL <= 4;

LEVEL Pseudocolumn

For each row returned by a hierarchical query, the LEVEL pseudocolumn returns 1 for a root row, 2 for a child of a root, and so on

SELECT employee_id, last_name, manager_id, LEVEL

FROM employees

CONNECT BY PRIOR employee_id = manager_id;

SELECT LPAD(' ',2*(LEVEL-1)) || last_name ORG_CHART,

employee_id, manager_id, job_id

FROM employees

START WITH job_id = 'AD_VP'

CONNECT BY PRIOR employee_id = manager_id;

SYS_CONNECT_BY_PATH

Returns the path of a column value from root to node, with column values separated by char for each row returned by CONNECT BY condition

SYS_CONNECT_BY_PATH(, )

See CONNECT_BY_ISCYCLE demo

Function Demo

Use A Function To Receive The Current Node and Search for Parents of the Current Node

CREATE OR REPLACE FUNCTION permissions_sub_tree_root (

the_id IN NUMBER,

the_level IN NUMBER)

RETURN NUMBER IS

sub_tree_root NUMBER(10);

BEGIN

SELECT id

INTO sub_tree_root

FROM hierarchy

WHERE level = the_level

-- Connect 'upwards', i.e. find the parent

CONNECT BY PRIOR PARENT = id

START WITH ID = the_id;

RETURN sub_tree_root;

END permissions_sub_tree_root;

/

SELECT id, name, username

FROM (

SELECT ID, PARENT, NAME,permissions_sub_tree_root(id, LEVEL) ROOT

FROM hierarchy

CONNECT BY PRIOR id = PARENT) HIERARCHY, permissions

WHERE ROOT = hierarchy_id;

GROUP BY Demo

Group By Demo with CONNECT_BY_ROOT and

CONNECT_BY_PRIOR

SELECT name, SUM(salary) "Total_Salary"

FROM (

SELECT CONNECT_BY_ROOT last_name "Name", salary

FROM employees

WHERE department_id = 110

CONNECT BY PRIOR employee_id = manager_id)

GROUP BY name;

Demos

Indenting

col lname format a30

SELECT LPAD(' ', level*2, ' ') || last_name LNAME, d.department_id

FROM employees e, departments d

WHERE e.department_id = d.department_id

START WITH employee_id = 100

CONNECT BY PRIOR e.employee_id = e.manager_id;

Hierarchical Query with IN

In a [NOT] IN condition in a WHERE clause, if the right-hand side of the condition is a subquery, you cannot use LEVEL on the left-hand side of the condition. However, you can specify LEVEL in a subquery of the FROM clause to achieve the same result. For example, the following statement is not valid:

SELECT employee_id, last_name FROM employees

WHERE (employee_id, LEVEL)

IN (SELECT employee_id, 2 FROM employees)

START WITH employee_id = 2

CONNECT BY PRIOR employee_id = manager_id;

But the following statement is valid because it encapsulates the query containing the LEVEL information in the FROM clause:

SELECT v.employee_id, v.last_name, v.lev

FROM (

SELECT employee_id, last_name, LEVEL lev

FROM employees v

START WITH employee_id = 100

CONNECT BY PRIOR employee_id = manager_id) v

WHERE (v.employee_id, v.lev) IN (

SELECT employee_id, 2 FROM employees);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值