Reputation: 45135
Follow up from here: Getting lowest level in a tree from any higher level with a self-join
I realized that I was actually asking the wrong question. I have a hierarchical table that looks something like this:
Type | Code | Parent_Type | Parent_Code
4 | 123 | 2 | 1
4 | 234 | 2 | 1
6 | 1234 | 4 | 123
6 | 2345 | 4 | 234
7 | 12345 | 6 | 1234
7 | 23456 | 6 | 1234
7 | 34567 | 6 | 2345
It maps "type 2" codes to "type 4", "type 4" to "type 6" and "type 6" to "type 7". The previous question (and answer) dealt with how to select all the type 7 codes under any single parent code. So, for example, how to get all the type 7 codes under type 2, code 1.
But what I actually need to do is join this table with a list of types and codes. So for example, I might have a table:
Type | Code
4 | 123
6 | 7851
And what I need to do is get all the level 7 codes under both those codes. In other words, (I think) I need to flatten the hierarchy into something like this:
Type | Code | Parent_Type | Parent_Code
7 | 12345 | 2 | 7
7 | 23456 | 2 | 7
7 | 34567 | 2 | 7
7 | 12345 | 4 | 123
7 | 23456 | 4 | 123
7 | 34567 | 4 | 234
7 | 12345 | 7 | 12345 // Note: these last three might not
7 | 23456 | 7 | 23456 // be strictly needed
7 | 34567 | 7 | 34567
So then I could do something like:
select p.type, p.code from myOtherTable o join mytable p on o.type = p.parent_type
and o.code = p.parent_code
To try and flatten the original table, I've tried some variations on the answer to my original question, but no really had much luck. For example:
with cte
as (
select p.type, p.code, p.parent_type, p.parent_code
from mytable as p
where parent_type = 2
union all
select c.type, c.code, c.parent_type, c.parent_code
from mytable as c
inner join cte on c.parent_code = cte.code
)
select *
from cte
Does nothing useful other than mess up the ordering of the table if I'd just directly called:
select * from mytable
Upvotes: 0
Views: 112
Reputation: 31198
Sounds like a recursive CTE should do the trick:
WITH cteTree As
(
SELECT
T.Type,
T.Code,
T.Parent_Type,
T.Parent_Code
FROM
RecordsToFind As F
INNER JOIN Tree As T
ON T.Type = F.Type
And T.Code = F.Code
UNION ALL
SELECT
T.Type,
T.Code,
T.Parent_Type,
T.Parent_Code
FROM
cteTree As F
INNER JOIN Tree As T
ON T.Parent_Type = F.Type
And T.Parent_Code = F.Code
WHERE
F.Type != 7
)
SELECT
Type,
Code,
Parent_Type,
Parent_Code
FROM
cteTree
WHERE
Type = 7
;
http://sqlfiddle.com/#!3/cc4ee/9
Upvotes: 1