我有一个数据库,其中包含使用邻接列表模型存储的类别层次结构。
层次结构深 3 层(不包括虚构的根节点),包含大约 1700 个节点。第二层和第三层的节点可以有多个父节点。多对多关系使用一个附加表,如下所示:
CREATE TABLE dbo.Category(
id int IDENTITY(1,1) NOT NULL,
name varchar(255) NOT NULL,
)
CREATE TABLE dbo.CategoryHierarchy(
relId int IDENTITY(1,1) NOT NULL,
catId int NOT NULL,
parentId int NOT NULL,
)
如果我转向使用传递闭包表方法(出于数据完整性等原因),是否有一个相对简单的查询可以执行来生成闭包表的值? (使用 SQL Server 2005)
我浏览过文章和演示文稿,例如 Bill Karwin 的 Models for hierarchical data但它只对单个节点进行插入查询,我需要很长时间才能创建这样的树。
谢谢。
编辑:
CategoryHierarchy表中的RelID纯粹是为了主键,与Category表的节点id无关。
另外,闭包表是指这样的表:
CREATE TABLE ClosureTable (
ancestor int NOT NULL,
descendant int NOT NULL,
[length] int NOT NULL,
)
其中前两列是复合主键,并且是 Category.id 的单独外键。
最佳答案
我试图弄清楚同样的事情,但希望在递归 CTE 中得到它。这对你来说是行不通的(SQL Server 2008+),但对于其他人来说,这就是我最终得到的结果。
关键是 anchor 不是您的根节点(其中 parent_id IS NULL
),而是闭包中的所有零深度行表。
表格
CREATE TABLE dbo.category (
id INT IDENTITY(1, 1) NOT NULL,
parent_id INT NULL
)
数据
INSERT INTO dbo.category (id, parent_id)
VALUES
(1, NULL),
(2, 1),
(3, 1),
(4, 2)
热膨胀系数
WITH category_cte AS
(
SELECT
id AS ancestor,
id AS descendant,
0 AS depth
FROM dbo.category
UNION ALL
SELECT
CTE.ancestor AS ancestor,
C.id AS descendant,
CTE.depth + 1 AS depth
FROM dbo.category AS C
JOIN category_cte AS CTE
ON C.parent_id = CTE.descendant
)
SELECT * FROM category_cte
结果
ancestor descendant depth
-------- ---------- -----
1 1 0 <- anchor query
2 2 0
3 3 0
4 4 0
2 4 1 <- first recursive query
1 2 1
1 3 1
1 4 2 <- second recursive query
关于sql - 如何使用邻接表中的数据创建闭包表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12621873/