oracle hierarchical query

Hierarchical Queries

If a table contains hierarchical data, then you can select rows in a hierarchical order using the hierarchical query clause:

Text description of hierarchical_query_clause

[START WITH condition] CONNECT BY condition

  • START WITH specifies the root row(s) of the hierarchy.
  • CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy. In a hierarchical query, one expression in condition must be qualified with the PRIOR operator to refer to the parent row. For example,

·                ... PRIOR expr = expr

·                or

·                ... expr = PRIOR expr

·                 

If the CONNECT BY condition is compound, then only one condition requires the PRIOR operator. For example:

CONNECT BY last_name != 'King' AND PRIOR employee_id = manager_id

 

In addition, the CONNECT BY condition cannot contain a subquery.

PRIOR is a unary operator and has the same precedence as the unary + and - arithmetic operators. It evaluates the immediately following expression for the parent row of the current row in a hierarchical query.

PRIOR is most commonly used when comparing column values with the equality operator. (The PRIOR keyword can be on either side of the operator.) PRIOR causes Oracle to use the value of the parent row in the column. Operators other than the equal sign (=) are theoretically possible in CONNECT BY clauses. However, the conditions created by these other operators can result in an infinite loop through the possible combinations. In this case Oracle detects the loop at run time and returns an error.

The manner in which Oracle processes a WHERE clause (if any) in a hierarchical query depends on whether the WHERE clause contains a join:

  • If the WHERE predicate contains a join, Oracle applies the join predicates before doing the CONNECT BY processing.
  • If the WHERE clause does not contain a join, Oracle applies all predicates other than the CONNECT BY predicates after doing the CONNECT BY processing without affecting the other rows of the hierarchy.

Oracle uses the information from the hierarchical query clause to form the hierarchy using the following steps:

  1. Oracle processes the WHERE clause either before or after the CONNECT BY clause depending on whether the WHERE clause contains any join predicates (as described in the preceding bullet list).
  1. Oracle selects the root row(s) of the hierarchy--those rows that satisfy the START WITH condition.
  1. Oracle selects the child rows of each root row. Each child row must satisfy the condition of the CONNECT BY condition with respect to one of the root rows.
  1. Oracle selects successive generations of child rows. Oracle first selects the children of the rows returned in step 3, and then the children of those children, and so on. Oracle always selects children by evaluating the CONNECT BY condition with respect to a current parent row.
  1. If the query contains a WHERE clause without a join, then Oracle eliminates all rows from the hierarchy that do not satisfy the condition of the WHERE clause. Oracle evaluates this condition for each row individually, rather than removing all the children of a row that does not satisfy the condition.
  1. Oracle returns the rows in the order shown in Figure below. In the diagram, children appear below their parents.

 

To find the children of a parent row, Oracle evaluates the PRIOR expression of the CONNECT BY condition for the parent row and the other expression for each row in the table. Rows for which the condition is true are the children of the parent. The CONNECT BY condition can contain other conditions to further filter the rows selected by the query. The CONNECT BY condition cannot contain a subquery.

If the CONNECT BY condition results in a loop in the hierarchy, then Oracle returns an error. A loop occurs if one row is both the parent (or grandparent or direct ancestor) and a child (or a grandchild or a direct descendent) of another row.

Note:

In a hierarchical query, do not specify either ORDER BY or GROUP BY, as they will destroy the hierarchical order of the CONNECT BY results. If you want to order rows of siblings of the same parent, then use the ORDER SIBLINGS BY clause. See order_by_clause.

層次查詢的默認排序是中序深度優先遍歷

例子:

如有表TU_HIER

有兩個col_subcol_parent,分別代表子節點和父節點

select * from TU_HIER

--where col_sub <> '002'

CONNECT BY col_parent = PRIOR col_sub

--and col_sub <> '002'

start with col_sub = '001'

ORDER SIBLINGS BY col_sub

需要注意的是

CONNECT BY中的篩選條件會立即生效,並影響其子樹的生成,如col_sub <> '002',則以002爲根的整棵子樹都會被去除,不會出現在查詢結果中。

Where中的篩選條件會等到所有連接都完成,再對最終的結果集統一進行篩選,如where col_sub <> '002',則只有002會被去除,而以002爲根節點的其他子節點不會被去除。

order siblings by在默認排序基礎上對兄弟節點進行進一步排序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章