Problem-solving without a Teradata Recursive Query
In our example, we want to represent a corporate hierarchy. Without recursion, this can be done, e.g., with the query shown below:
SELECT -- Concatenation of all Companies CASE WHEN Level >= 3 THEN TRIM(t03.Company_Id) || '.' ELSE '' END || CASE WHEN Level >= 2 THEN TRIM(t02.Company_Id) || '.' ELSE '' END || TRIM(t01.Company_Id) AS Company_Hierarchy -- Level Calculation ,CASE NULL WHEN t01.Parent_Company_Id THEN 1 WHEN t02.Parent_Company_Id THEN 2 WHEN t03.Parent_Company_Id THEN 3 END AS Level FROM DWHPro.Company t01 LEFT OUTER JOIN DWHPro.Company B ON t01.Parent_Company_Id = t02.Company_Id LEFT OUTER JOIN DWHPro.Company t03 ON t02.Parent_Company_Id = t03.Company_Id ORDER BY 1 ;
The above query has several harmful properties:
- We must know the number of hierarchy levels.
If too few levels are considered, the query returns incorrect results. If too many hierarchy levels are considered, unnecessary joins are caused.
- If the number of hierarchy levels changes, the following changes to the SQL statement are necessary:
– Joins need to be added or removed
– One CASE Statement has to be adjusted to determine the levels
– One CASE Statement has to be adjusted to calculate the Hierarchy
Problem-solving with a Teradata Recursive Query
WITH RECURSIVE Hierarchy (Company_Hierarchy, Company_Id, Level) AS ( -- SELECT TRIM(Company_Id) (VARCHAR(1024)) AS Company_Hierarchy , Company_Id , 1 AS Level FROM DWHPro.Org WHERE Parent_Company_Id IS NULL UNION ALL SELECT t02.Company_Hierarchy || '.' || TRIM(t01.Company_Id) AS Company_Hierarchy , t01.Company_Id , t02.Level + 1 AS Level FROM DWHPro.Org t01 ,Hierarchy t02 WHERE t01.Parent_Company_Id = t02.Company_Id AND Level <= 10 -- limit to avoid infinite loop errors ) SELECT Company_Hierarchy, Company_Id, Level FROM Hierarchy ORDER BY 1 ;
The above recursive query has several benefits:
- Only the required number of recursive join steps are executed
- We can limit the number of levels to avoid “runaway” recursions
The only change might be needed to increase the size of column Company_Hierarchy (in the above example, set to VARCHAR(1024))
Which of the two queries has the better performance cannot be said in general. It depends on the data demography. We suggest choosing the recursive variant in principle since it is more flexible. If performance is an essential factor, we recommend measuring the resource consumption in table DBC.DBQLOGTBL for both variants and then decide accordingly.