如何在Sql Server 2005存储过程中迭代分层数据?

时间:2010-06-14 10:45:45

标签: sql sql-server-2005 tsql

我有一个SqlServer2005表“Group”,类似于以下内容:

Id (PK, int)
Name (varchar(50))
ParentId (int)

其中ParentId引用Group表中的另一个Id。这用于建模层次组,例如:

Group 1 (id = 1, parentid = null)
    +--Group 2 (id = 2, parentid = 1)
    +--Group 3 (id = 3, parentid = 1)
           +--Group 4 (id = 4, parentid = 3)
Group 5 (id = 5, parentid = null)
    +--Group 6 (id = 6, parentid = 5)

你得到了照片

我有另一张桌子,为简化起见,我们称之为“数据”,它看起来像:

Id (PK, int)
Key (varchar)
Value (varchar)
GroupId (FK, int)

现在,我正在尝试编写一个存储过程,它可以为我提供给定组的“数据”。例如,如果我查询组1,它返回来自Data的键值对,其中groupId = 1.如果我查询组2,它返回groupId = 1的KVP,然后与具有groupId =的那些联合2(并替换重复的密钥)。

理想情况下,如果存在循环(即,如果组1的父组是组2,组2的父组是组1),则优先级也会优雅地失败。

有没有人有过编写这样一篇文章的经验,或者知道如何实现这一目标?

谢谢你们,非常感谢,

亚历

1 个答案:

答案 0 :(得分:3)

这可以使用递归查询和CTE来完成

;WITH KeyValue AS
(
SELECT G.Id, G.Name, D.Key, D.Value, 0 AS level
FROM Group G
LEFT JOIN Data D ON G.Id = D.GroupID
WHERE G.Id = @your_top_level_root

UNION ALL

SELECT G.Id, G.Name, D.Key, D.Value, K.level + 1
FROM KeyValue K
JOIN Group G ON G.ParentId = K.Id
LEFT JOIN Data D ON G.Id = D.GroupID
)
SELECT * FROM KeyValue