【发布时间】:2020-08-31 14:47:46
【问题描述】:
为简单起见,我的架构:
-
文件夹表(FolderId、ParentFolderId)
-
DeviceFolderProperties 表(FolderId、LogDataRetentionDaysEvent)
并非每个文件夹都有保留日。然而,这是一个继承的值。如何在 SQL 中编写一些东西来返回每个文件夹及其保留日期,如果为 null,则返回其继承值。
继承有多个层次,因此需要遍历树。
这是我尝试过的:
;
WITH [cte]
AS
(
SELECT f.FolderId, f.ParentFolderId, dfp.LogDataRetentionDaysEvent
FROM [Folders] f
LEFT JOIN DeviceFolderProperties dfp
ON f.FolderId = dfp.FolderId
),
[cte_collapse]
AS --recurse where r days is null
(
SELECT c.FolderId, c.ParentFolderId, c.LogDataRetentionDaysEvent
FROM [cte] c
WHERE c.LogDataRetentionDaysEvent IS NULL
UNION ALL
SELECT c.FolderId, c.ParentFolderId, ISNULL(c.LogDataRetentionDaysEvent, cc.LogDataRetentionDaysEvent)
FROM [cte] c
JOIN [cte_collapse] cc ON cc.FolderId = c.ParentFolderId
)
SELECT
*
FROM
[cte_collapse]
【问题讨论】:
-
SQL 中没有继承。您正在使用递归 CTE 执行分层查询。一个更简单且绝对快很多倍的方法是使用hierarchyid type 而不是父/子连接。
hierarchyid存储层次结构的“路径”,这使得查找子级就像查找path以根路径开头的行一样容易。这种搜索可以利用索引来加速查询
标签: sql sql-server left-join recursive-query hierarchical-query