Есть как минимум два способа сделать это.Вы упоминаете CTE в своем названии, так что я пойду с этим первым.По ссылке здесь У меня есть пример иерархического CTE, небольшого массажа, и он будет представлять родителей, а не детей:
WITH Hierarchy (Group_ID, Name, Parent_ID, Level) AS
(
SELECT Group_ID, Name, Parent_ID, Level
FROM T_Group
WHERE Contact_id = @Leaf
UNION ALL
SELECT g.Group_ID, g.Name, g.Parent_ID, g.Level
FROM T_Group g
INNER JOIN Hierarchy h ON g.Group_ID = h.Parent
)
Этот CTE будет помещен в хранимую процедуруили таблица User Defined Function, принимающая параметр @Leaf (конечный узел, для которого вы ищете. В вашем примере это 82, а затем 7).
Проблема в том, что иерархические CTE могут быть очень дорогими,особенно если вы работаете с более глубокими древовидными структурами или вызываетесь повторно.Кэширование может помочь, но есть и другие варианты.
Другой способ - сохранить иерархию родителей в объединенном со строкой поле рядом с вашими группами:
GROUP_ID NAME PARENT_ID LEVEL PARENTS
82 Advocacy 80 3 |7|80|82|
Затем можно сделать что-то вроде:
SELECT p.Group_ID, g.Name, g.Parent_ID, g.Level
FROM T_GROUP g
CROSS JOIN dbo.StringSplit('|', Parents) p
WHERE p.Value = g.Group_ID
, чтобы получить все данные родителей.Это имеет тенденцию быть намного более эффективным, чем использование CTE для обработки поиска.Это означает, что когда вы вставляете новые записи в GROUP, вы также должны создавать родительское поле.Обычно, чтобы справиться с этим, вы должны создать хранимую процедуру, которая создала для вас группу, при необходимости создав родительскую группу.