Call now: 252-767-6166  
Oracle Training Oracle Support Development Oracle Apps

 
 Home
 E-mail Us
 Oracle Articles
New Oracle Articles


 Oracle Training
 Oracle Tips

 Oracle Forum
 Class Catalog


 Remote DBA
 Oracle Tuning
 Emergency 911
 RAC Support
 Apps Support
 Analysis
 Design
 Implementation
 Oracle Support


 SQL Tuning
 Security

 Oracle UNIX
 Oracle Linux
 Monitoring
 Remote s
upport
 Remote plans
 Remote
services
 Application Server

 Applications
 Oracle Forms
 Oracle Portal
 App Upgrades
 SQL Server
 Oracle Concepts
 Software Support

 Remote S
upport  
 Development  

 Implementation


 Consulting Staff
 Consulting Prices
 Help Wanted!

 


 Oracle Posters
 Oracle Books

 Oracle Scripts
 Ion
 Excel-DB  

Don Burleson Blog 


 

 

 


 

 

 

 

 

Ancestors Query

SQL Tips by Donald Burleson

Logically, finding all the ancestors can be accomplished by swapping the roles of the two join operands in the descendants query. Once again, such a query will not be a good performer. In the section on materialized path encoding the problem was split into two parts: computing all the node encodings in the chain first, and extracting all the nodes by those keys from the database, second. Since a close tie between the materialized path and matrix encoding was introduced earlier, it would come as no surprise that we can perform the same trick with matrices.

Let's look into matrix encodings of parent and child nodes one more time:

The child just inherited the entries a11 and a21 from its parent. Therefore, to calculate the left row entries of the parent, just take them from the right row of the child matrix. The right row elements are the remainders of the division of the parent left row by the right row, and as an added bonus, the sibling order number n was obtained.

Let's demonstrate it on the familiar example of child node 1.3.2.5:

The modulo function calculates the remainders:

19-mod(107,19) = 7

11-mod(62,11) = 4

Let's double check the results:

107 = (5+1)*19 - 7

62 = (5+1)*11- 4

Hence, the parent encoding: 

This process continues as to find the grandfather:

And to find the grand grandfather:

which happens to be the root - a matrix with a22 = 0. Now that we have a list of ancestor matrices, how are they extracted from database? One solution would be by building a dynamic query like this:

select *
from MatrixTreeNodes
where a11=19 and a12=7 and a21=11 and a22=4
   or a11=7 and a12=2 and a21=4 and a22=1
   or a11=2 and a12=1 and a21=1 and a22=0

Though a better approach would be storing the ancestor encoding in a temporary Ancestors table, and using the generic query:

select n.*
from MatrixTreeNodes n, Ancestors a
where n.a11=a.a11 and n.a12=a.a12 and n.a21=a.a21 and n.a22=a.a22

Some RDBMS engines allow programming table functions so that the table of ancestor encodings can be produced as an output of such a function. Syntactically, the query would become:

select n.*
from MatrixTreeNodes n, Table(Ancestors(49,9,38,7)) a
where n.a11=a.a11 and n.a12=a.a12 and n.a21=a.a21 and n.a22=a.a22

Given the entries a11=107, a12=19, a21=62, and a22=11, the Ancestors table function is supposed to calculate the chain of ancestor encodings.

Converting Matrix to Path

The previous section revealed the identity connecting parent and child encoding and mentioned that a sibling order number n is a remainder of integer division floor((a11*(n+1)-a12)/a12). In our example, the node 1.3.2.5 is the 5th children of the node 1.3.2:

floor(107/19) = 5

floor(62/11) = 5

Working all the way to the root, the other numbers in the path can be found.

The path is generated in the order from the leaf to the root. Perhaps, it would be more convenient to generate it in the opposite order. The procedure is essentially the same, but applied to the transposed matrix.

Inserting Nodes

So far our attention was on queries. But how is the tree filled with nodes? The new node location is unambiguously defined by the node's parent and the node's position among the other children. Normally, given a parent, a new node is attached as the youngest child. Therefore, the node's insertion is accomplished in two steps:

1.      Query all the immediate children and find the oldest child

select max(floor(a11/a12)) as N from MatrixTreeNodes
where a11 = :parent_a12
and a21 = :parent_a22

where :parent_a12 and :parent_a22 are the host variables of the parent node encoding.

2.       Insert the node at the n-th position:

insert into MatrixTreeNodes (a11,a12,a21,a22) values
(:parent_a11*(:N+1) - :parent_a12,
 :parent_a11,
 :parent_a21*(:N+1) - :parent_a22,
 :parent_a21);

These two steps can be combined into a single insert as select statement.

Relocating Tree Branches

This is the section where matrix algebra really shines. Consider a tree branch located at the node encoded with matrix A, and suppose it is to be moved to the new location under node B. How would the encoding of some node C (which is located in the tree branch under A) change?

That is quite an easy task for materialized path encoding. First, find the path from the node A to C. Then, append it to node B. This idea transfers to matrices almost literally. The encoding of node C is a product of its ancestor A and some other matrix:

A X = C

Matrix X corresponds to the path from A to C. This path is appended to path B; the matrices are multiplied and thus the resulting encoding obtained is:

B X

The unknown matrix X is calculated via inverse matrix, so the final answer is:

B A-1 C

In order to translate this into SQL, the answer is expanded component-wise:

And can be coded in SQL as:

update MatrixTreeNodes c
set c.a11 = (:b12*:a21-:b11*:a22)*c.a11
           +(:b11*:a12-:b12*:a11)*c.a21
    c.a12 = (:b12*:a21-:b11*:a22)*c.a12
           +(:b11*:a12-:b12*:a11)*c.a22
    c.a21 = (:b22*:a21-:b21*:a22)*c.a11
           +(:b21*:a12-:b22*:a11)*c.a21
    c.a22 = (:b22*:a21-:b21*:a22)*c.a12
           +(:b21*:a12-:b22*:a11)*c.a22
where c.a11*:a21 >= c.a21*:a11  -- all the descendants of matrix
and   c.a11*:a22 >= c.a21*:a12  -- [[:a11,:a12][:a21,:a22]]

 

This is an excerpt from the new book SQL Design Patterns: The Expert Guide to SQL Programming by Vadim Tropashko

You can buy it direct from the publisher for 30%-off.


 

 
��  
 
 
Oracle Training at Sea
 
 
 
 
oracle dba poster
 

 
Follow us on Twitter 
 
Oracle performance tuning software 
 
Oracle Linux poster
 
 
 

 

Burleson is the American Team

Note: This Oracle documentation was created as a support and Oracle training reference for use by our DBA performance tuning consulting professionals.  Feel free to ask questions on our Oracle forum.

Verify experience! Anyone considering using the services of an Oracle support expert should independently investigate their credentials and experience, and not rely on advertisements and self-proclaimed expertise. All legitimate Oracle experts publish their Oracle qualifications.

Errata?  Oracle technology is changing and we strive to update our BC Oracle support information.  If you find an error or have a suggestion for improving our content, we would appreciate your feedback.  Just  e-mail:  

and include the URL for the page.


                    









Burleson Consulting

The Oracle of Database Support

Oracle Performance Tuning

Remote DBA Services


 

Copyright © 1996 -  2020

All rights reserved by Burleson

Oracle ® is the registered trademark of Oracle Corporation.