给出以下递归查询:
WITH DepartmentHierarchy (DepartmentID, Name, IsInactive, IsSpecial, ParentId, HierarchyLevel) AS
(
-- Base case
SELECT
DepartmentId,
Name,
IsInactive,
IsSpecial,
ParentId,
1 as HierarchyLevel
FROM StoreDepartment
WHERE ParentId IS NULL
UNION ALL
-- Recursive step
SELECT
d.DepartmentId,
d.Name,
d.IsInactive,
d.IsSpecial,
d.ParentId,
dh.HierarchyLevel + 1 AS HierarchyLevel
FROM StoreDepartment d
INNER JOIN DepartmentHierarchy dh ON
d.ParentId = dh.DepartmentId
) SELECT * FROM DepartmentHierarchy
我可以选择看起来像这样的数据:
DepartmentId, Name, IsInactive, IsSpecial, ParentId, HeirarchyLevel
1, Store, 0, 0, NULL, 1
2, Main Department 1, 0, 1, 2
3, Main Department 2, 0, 1, 2
4, Sub For Main 1, 0, 2, 3
此外,假设存在DepartmentId和ItemId的表(例如:DepartmentItemRelationship)。部门层次结构中的叶节点与此处的项目配对。
我希望我的递归查询只返回在其下面至少有一个叶子节点并且在department / item关系表中匹配的节点(在任何级别)。这些节点可能是6或7级,所以我不确定如何修改我的查询以确保包含这些。
谢谢, 凯尔
答案 0 :(得分:3)
您可以创建一个跟踪层次结构的路径列。然后,您只能在DepartmentItemRelationship表中添加具有匹配项的子节点。最后只获得至少有孩子的节点。
尝试这样的事情:
WITH DepartmentHierarchy (DepartmentID, Name, IsInactive, IsSpecial, ParentId, HierarchyLevel) AS
(
-- Base case
SELECT
'/'+cast( DepartmentId as varchar(max)) as [path]
DepartmentId,
Name,
IsInactive,
IsSpecial,
ParentId,
1 as HierarchyLevel
FROM StoreDepartment
WHERE ParentId IS NULL
UNION ALL
-- Recursive step
SELECT
dh.[path] +'/'+ cast( d.DepartmentId as varchar(max)) as [path]
d.DepartmentId,
d.Name,
d.IsInactive,
d.IsSpecial,
d.ParentId,
dh.HierarchyLevel + 1 AS HierarchyLevel
FROM StoreDepartment d
INNER JOIN DepartmentHierarchy dh ON
d.ParentId = dh.DepartmentId
where exists ( select top 1 1
from DepartmentItemRelationship di
where di.DepartmentId = d.DepartmentId )
)
SELECT *
FROM DepartmentHierarchy dh
where exists ( select top 1 1
from DepartmentHierarchy
where charindex('/'+dh.DepartmentID+'/',[path]) > 0)
答案 1 :(得分:1)
如果我理解正确,您希望所有节点都高于叶级别一级?
您实际上并不需要递归查询。您所需要的只是首先找到叶子节点,然后选择所有父节点。
WITH LeafNodeParents AS
(
SELECT DISTINCT ParentId
FROM StoreDepartment
WHERE DepartmentId NOT IN
(
SELECT DISTINCT ParentId FROM StoreDepartment
)
)
SELECT d.DepartmentId, d.Name, d.IsInactive, d.IsSpecial, d.ParentId
FROM LeafNodeParents p
INNER JOIN StoreDepartment d
ON d.DepartmentId = p.ParentId
唯一不会告诉你的是关卡。我不确定你需要多么糟糕。如果不这样做,这应该比递归版本更好;如果你这样做,看起来Jose的查询就可以了(通过快速浏览判断)。