"Fun" with cyclic references:
Suppose I have a table ELEMENTS which contain a hierarchy of elements, modeled by a father ID.
The father ID field is null for the root.
All other records have a non-null father id with the (autosequenced) primary key (ID
) of the father element.
For example, using
SELECT *
FROM Elements
WHERE FATHER_ID not in (SELECT ID FROM Elements)
I can find all elements that have invalid father references (FATHER_ID
is not a foreign key, let's assume that in this example).
But how can I find elements that do have a valid father reference BUT whose chain of father references does not end in the root? I think this can only happen for cyclic references, for example A is the father of B, but B is the father of A, too. Such a "subtree" is not linked to the root and thus is not part of the main tree. I want to find such subtrees.
Of course, I am looking for a query that delivers those elements that lead to a cyclic reference no matter how long the chain of references may be.
Is that possible in SQL, or do I need an iterative solution?
You can run it in the Query Window of SQL Server Management Studio; the output will be displayed as in the Message section. Each line is a circular reference, with a link list of tables that create the circle.
Use hierarchyid as a data type to create tables with a hierarchical structure, or to describe the hierarchical structure of data that is stored in another location. Use the hierarchyid functions in Transact-SQL to query and manage hierarchical data.
In the world of relational databases circular references are schema structures where foreign keys relating the tables create a loop. Circular references cause special types of issues when trying to synchronize two relational database where the foreign keys are enforced.
SELECT n.*, CONNECT_BY_ROOT(id), level
FROM elements n
START WITH
id IN
(
SELECT MIN(id)
FROM (
SELECT id, CONNECT_BY_ROOT(id) AS root
FROM elements
START WITH
id IN
(
SELECT id
FROM elements n
WHERE CONNECT_BY_ISCYCLE = 1
CONNECT BY NOCYCLE
father_id = PRIOR id
)
CONNECT BY NOCYCLE
id = PRIOR father_id
)
GROUP BY
root
)
CONNECT BY NOCYCLE
id = PRIOR father_id
You may want to read this article:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With