Tsql CTE-反向层次结构

Tsql CTE-反向层次结构,tsql,sql-server-2005,Tsql,Sql Server 2005,我需要生成一组特定联系人的面包屑状路径 T_GROUP存储组的实际层次结构: GROUP_ID NAME PARENT_ID LEVEL 7 g1 NULL 1 80 Workgroups 7 2 82 Advocacy 80 3 T_CONTACT_GROUP表存储属于联系人的组: CONTACT_ID G

我需要生成一组特定联系人的面包屑状路径

T_GROUP存储组的实际层次结构:

GROUP_ID    NAME            PARENT_ID   LEVEL
    7      g1              NULL         1
    80    Workgroups      7            2
    82    Advocacy        80           3
T_CONTACT_GROUP表存储属于联系人的组:

CONTACT_ID  GROUP_ID 
55          82
56            7
55            7
现在,我想得到如下联系人Id 55的结果集:请注意,g1在预期结果集中出现了两次,因为联系人55也被分配到了第7组

contactId GROUP_ID NAME PARENT_ID   LEVEL
55        7     g1      NULL        1
55        80       g1|Workgroups 7 2
55       82        g1|Workgroups|Advocacy 80 3
55       7         g1 NULL 1

至少有两种方法可以做到这一点。 你在标题中提到了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将被放置在一个存储过程或表用户定义函数中,参数为@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处理查找更有效。这确实意味着,当您向组中插入新记录时,您也必须构建父字段。通常,要处理此问题,您需要创建一个存储过程来为您创建组,并根据需要构建父级。

至少有两种方法。 你在标题中提到了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将被放置在一个存储过程或表用户定义函数中,参数为@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处理查找更有效。这确实意味着,当您向组中插入新记录时,您也必须构建父字段。通常,要处理这个问题,您需要创建一个存储过程来为您创建组,并根据需要构建父级