Documente Academic
Documente Profesional
Documente Cultură
Traverse Hierarchies
Analyze data and prevent problems with recursive queries.
by Ralph Meira
Querying Hierarchies
The recursive query syntax was created to enable SQL to query hierarchical data of an unknown depth. Using the WITH clause, you
can define derived tables before the main
query instead of within it. A recursive
query contains at least one reference
to its name within its own definition
and is composed of these parts:
>A
seed query UNIONed
to an iterative (recursive) segment
> At least one logical
condition to prevent infinite loops
from occurring
Simple Hierarchy
figure 1
1
11
111
111
1
11
1111
11111
22
1111
11111
22
2222
222
11
11
33
111
222
1
3
33
333
figure 2
111
22
22
11111
1
11111
1
111111
111
111111
111
333
2222
33
33
222
222
2222
2222
333
333
22222 22222
This hierarchy has some data problems: The green lines highlight
(a) a cyclic loop (1,11,111,1,) and (b) a lower-level child item 11111 as
a parent to 222, which is higher up in the hierarchy. There is also a
missing link between 22 and 222.
table 1
Parent-Child Rules
PARENT_ID
SQL SAMPLE 1
WITH RECURSIVE TREE
( LEVEL, PARENT_ID, CHILD_ID, PATH) AS
( SELECT 0 AS LEVEL,
E.PARENT_ID,
E.CHILD_ID,
CAST (E.PARENT_ID
AS VARCHAR(200)) AS PATH
FROM TABLE_1 E
WHERE E.PARENT_ID = 0
UNION ALL
SELECT TREE.LEVEL +1 ,
S.PARENT_ID, S.CHILD_ID,
CAST (TREE.PATH || S.PARENT_ID
AS VARCHAR(200)) AS PATH
CHILD_ID
11
22
33
11
111
11
1111
22
222
33
333
222
2222
1111
11111
SQL SAMPLE 2
REPLACE RECURSIVE VIEW TREE_V
( LEVEL, PARENT_ID, CHILD_ID, PATH) AS
( SELECT 0 AS LEVEL,
E.PARENT_ID,
E.CHILD_ID,
CAST (E.PARENT_ID
AS VARCHAR(200)) AS PATH
FROM TABLE_1 E
WHERE E.PARENT_ID = 0
UNION ALL
SELECT TREE_V.LEVEL +1 ,
S.PARENT_ID, S.CHILD_ID,
CAST (TREE_V.PATH || S.PARENT_ID
AS VARCHAR(200)) AS PATH
FROM TREE_V, TABLE_1 S
WHERE TREE_V.CHILD_ID=S.PARENT_ID
AND TREE_V.LEVEL < 10
AND POSITION (S.PARENT_ID IN TREE_V.PATH)
<1
);
SQL SAMPLE 3
SELECT PARENT_ID, CHILD_ID,
MIN(LEVEL)+1 AS DEPTH,
PATH||CHILD_ID AS PATH,
CASE
WHEN ( POSITION(CHILD_ID IN PATH) > 0)
THEN CYCLIC ELSE END AS CYCLIC
FROM TREE_FIG2_V GROUP BY 1,2,4,5
MINUS
table 2
PARENT_ID
CHILD_ID
DEPTH
PATH
CYCLIC
11
11
111
11
111
111
11
111
11
1111
11
1111
1111
11111
11
1111
11111
11111
222
11
1111
11111
222
222
2222
11
1111
11111
222
2222
2222
22222
11
1111
11111
222
2222
22
22
22
222
22
222
222
2222
22
222
2222
2222
22222
22
222
2222
33
33
33
333
33
333
333
2222
33
333
2222
2222
22222
33
333
2222
33
22222
33
22222
CYCLIC
22222
22222
22222
There are many available paths when starting at Node 0. The cyclic path is correctly
flagged in the last column.
Different Paths
table 3
PARENT_ID
CHILD_ID
DEPTH
PATH
CYCLIC
111
11
111
CYCLIC
1111
11111
11
1111
11111
222
11111
222
11
1111
11111
222
2222
222
2222
11
1111
11111
222
2222
2222
22222
11
1111
11111
22
222
22
222
2222
22
222
2222
2222
22222
22
222
2222
333
2222
33
333
2222
2222
22222
33
333
2222
33
22222
33
22222
22222
222
22222
22222
This table shows how the paths differ between figures 1 and 2.
xx
l 3TeradataMagazine.com
PAGE
l Teradata Magazine l Q3/2011 l 2011 Teradata Corporation l AR-6393
QX/201X l TDM l XX