【发布时间】:2011-08-14 20:23:51
【问题描述】:
对于含糊的标题,我深表歉意。我想不出如何最好地总结这个问题。我有一个分层表(例如ID int, ParentID int),需要为ID 生成一个子树。这可以通过递归 CTE 轻松完成。困难在于,对于每个节点,我需要计算一组相应值的运行按位或,然后对父节点计算得到相同值的位或。这意味着每个节点都继承其父节点的位掩码,并且可以设置自己的附加位。我可以使用OUTER APPLY 和我问过的earlier question 中提到的技术在CTE 的锚成员中计算这个值。不幸的是,我不能在 CTE 的递归部分中以相同的方式计算它,因为它使用 SUM 并且不允许在那里聚合。
有没有办法重组它来做我想做的事?
declare @ID int
set @ID = 1
;with _Bits_(RowNum, BitMask) as
(
select
1,
1
union all select
RowNum + 1,
BitMask * 2
from
_bits_
where
RowNum < 31
),
_Tree_ as
(
select
a.ID,
a.ParentID,
b.BitMask
from
Tree a
outer apply
(
select
sum(distinct y.BitMask) as BitMask
from
BitValues x
inner join _Bits_ y
on (x.Value & y.BitMask) <> 0
where
x.ID = a.ID
) b
where
a.ID = @ID
union all select
a.ID,
a.ParentID,
c.BitMask | b.BitMask
from
Tree a
inner join _Tree_ b
on b.ID = a.ParentID
outer apply
(
select
sum(distinct y.BitMask) as BitMask
from
BitValues x
inner join _Bits_ y
on (x.Value & y.BitMask) <> 0
where
x.ID = a.ID
) c
)
select * from _Tree_
编辑
如果有助于概念化问题:层次结构很像目录结构,而位掩码就像从父文件夹继承的权限。
示例数据
create table Tree (ID int primary key, ParentID int null foreign key references Tree (ID))
insert Tree values (1, null)
insert Tree values (2, 1)
insert Tree values (3, 1)
create table BitValues (ID int not null foreign key references Tree (ID), BitMask int not null)
insert BitValues values (1, 1)
insert BitValues values (2, 2)
insert BitValues values (2, 4)
insert BitValues values (3, 8)
insert BitValues values (3, 16)
insert BitValues values (3, 32)
对于@ID 1,我希望查询返回:
【问题讨论】:
-
你能给我们一些示例数据吗?
-
@Hogan:我用测试数据更新了问题。
-
我知道如何解决这个问题——我应该可以在几个小时内发帖——必须做通勤的事情。
-
@Hogan - 酷。我期待看到你的想法。我也想出了一个解决方案,但它是 lot 的代码。我不能发布它,因为它包含机密数据,而且清理起来太多了。如果您或其他人在接下来的一两天内没有发布答案,我可能会发布我采取的一般步骤。
标签: sql-server sql-server-2005 tree common-table-expression recursive-query