我为模糊的标题道歉。我想不出如何最好地总结这个问题。我有一个分层表(例如ID int, ParentID int
),需要为ID
. 这可以通过递归 CTE 轻松完成。困难在于,对于每个节点,我需要计算一组相应值的运行按位或,然后对父节点计算结果与相同值的位或。这意味着每个节点都会继承其父节点的位掩码,并且可以设置自己的附加位。我可以使用我之前问过的问题OUTER APPLY
中提到的技术来计算 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,我希望查询返回:
+----+----------+---------+ | 身份证 | 家长 ID | 位掩码 | +----+----------+---------+ | 1 | 空 | 1 | | 2 | 1 | 7 | | 3 | 1 | 57 | +----+----------+---------+