Advanced SQL queries (hierarchical queries, recursion)

Hierarchical Query

Hierarchical structure may be understood as a tree data structure, formed by the node. Such as the common organizational structure consists of a general manager, deputy general manager of the Minister of multiple, multiple departments. Another example in the manufacturing of a product will have multiple sub-parts. As a simple example, as shown in FIG.

Hierarchical graph .png

Automobile as the root node, the following vehicle comprising an engine and two child nodes, the leaf nodes of other child node in turn constituted. (Leaf node represents no child nodes)

If we want the product information stored in the database, the data table will be formed as follows.

Table structure .png

We use parent_product_id column of the current product which is a product of the Father.

So how hierarchical query using SQL? Here we must use the START WITH and CONNECT BY syntax.
We first write SQL, again explain the meaning.

SELECT
  level,
  id,
  parent_product_id,
  name
FROM product START WITH id = 1 CONNECT BY prior id = parent_product_id ORDER BY level

Query results are as follows:

Query 1.png

Explain: LEVEL column indicates the current products are the first few levels. START WITH represent a product from which to start the query, CONNECT BY PRIOR shows the relationship between parent and child nodes, ID of each product points to a parent product.

If we changed the starting point START WITH query id = 2, re-run the above SQL statement will get the following results:

Query 2.png

Because the product id = 2 is the body, we can only be found in the body following sub-products.

Of course, we can beautify the query results, making it more layered, we make the following front LEVEL root can add a few spaces. The above SQL slightly modified. Is added to every preceding LEVEL 2 * (LEVEL-1) spaces, such that the second layer will increase two spaces, the third layer will increase four spaces.

SELECT
  level,
  id,
  parent_product_id,
  LPAD(' ', 2 * (level - 1)) || name AS name FROM product START WITH id = 1 CONNECT BY prior id = parent_product_id

Query results have layered, as shown below:

Figure III .png

Recursive queries

In addition to using the method we said above, you can also use recursive queries to get the same result. Recursion will use the WITH statement. Common WITH statement can be seen as a sub-queries, we can use this sub-queries directly WITH outside.

When recursive queries, we are inside the WITH statement to refer this sub-queries. Using the example above, we use the WITH statement to query.

WITH
  temp_product (product_level, id, parent_product_id,name) AS
  (
    SELECT
      0 AS product_level,id,parent_product_id,name FROM product WHERE parent_product_id IS NULL UNION ALL SELECT tp.product_level + 1,p.id, p.parent_product_id, p.name FROM product p JOIN temp_product tp ON p.parent_product_id=tp.id ) SELECT product_level, id, parent_product_id, LPAD(' ', 2 * product_level) || name AS NAME FROM temp_product;

We first SELECT statement inquiries from the root, and is set to level = 0, the second SELECT statement associated WITH statement itself, and each floor level plus 1 recursively.

Query results are as follows:

WITH.png

We can see that the first column is to demonstrate the product level, and we check out the above results are consistent.

WITH use recursion can have a depth-first search and breadth-first search, what does that mean? Is a breadth-first sub line before returning back to the fraternity first row, as shown above, the first two brothers body and engine return line, after following their sub-lines. In contrast, depth first priority is to return child rows of a parent node another brother back row.

We only need to add the following statement at the top of SELECT statements to be depth-first search query.

  search depth FIRST BY id
  SET order_by_id

As a result, returns the child to see first row in each parent, the parent node to another and back.

Depth First .png

Similarly, breadth-first using the following SQL statement

  search breadth FIRST BY id
  SET order_by_id

Guess you like

Origin www.cnblogs.com/xingkongzhizhu/p/12092388.html