Context:
Let's say that I have table that has a FOREIGN KEY which references its own PRIMARY KEY, like this:
|---------------------|------------------|------------------|
| ID | NAME | PARENT_ID |
|---------------------|------------------|------------------|
| 01 | John | 04 |
|---------------------|------------------|------------------|
| 02 | Paul | 01 |
|---------------------|------------------|------------------|
| 03 | George | 02 |
|---------------------|------------------|------------------|
| 04 | Ringo | 03 |
|---------------------|------------------|------------------|
Problem:
So as you see there is looped hierarchy: Ringo->George->Paul->John->Ringo->George->Paul->John->etc.
Question:
Whether there is a SQL select that can detect such loops?
I know that I can write recursive PL/SQL procedure but I prefer solution with "pure" SQL.
Thank you in advance
You can use a CONNECT BY query with the CONNECT_BY_ISCYCLE pseudo-column to look for loops - see example from Oracle docs:
SELECT last_name "Employee", CONNECT_BY_ISCYCLE "Cycle"
FROM employees
WHERE level <= 3
AND department_id = 80
START WITH last_name = 'King'
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;
You can do this with connect by nocycle and connect_by_iscycle. For your table structure, that would look like:
select id, name, parent_id, connect_by_iscycle
from mytable
connect by nocycle id = prior parent_id
start with id = 4
connect by nocycle causes the query to stop iterating when a cyle is met, and pseudo-column connect_by_iscycle contains a flag that indicates at which point it happened, as shown in this demo:
ID | NAME | PARENT_ID | CONNECT_BY_ISCYCLE -: | :----- | --------: | -----------------: 4 | Ringo | 3 | 0 3 | George | 2 | 0 2 | Paul | 1 | 0 1 | John | 4 | 1 --> cycle detected here
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