我找到了一篇非常有帮助的文章: Simplest way to do a recursive self-join in SQL Server?
假设在这个例子中有另一个名为" Quantity"存储看起来像这样的整数:
PersonID | Initials | ParentID | Quantity
1 CJ NULL 1
2 EB 1 2
3 MB 1 1
4 SW 2 1
5 YT NULL 1
6 IS 5 1
如果我要求CJ的层次结构,那就是
PersonID | Initials | ParentID | Quantity | HasSubordinate
1 CJ NULL 2 1
2 EB 1 1 1
3 MB 1 1 1
4 SW 2 1 0
列HasSubordinate指定层次结构中的最后一个个体。我想显示层次结构中的最后一个人,每个前面一行的数量相乘。在这种情况下,数量将是2(2 x 1 x 1 x 1 = 2)。
PersonID | Initials | ParentID | Quantity | HasSubordinate
4 SW 2 2 0
我的代码:
WITH q AS
(
SELECT *
FROM mytable
WHERE PersonID = 1
UNION ALL
SELECT m.*
FROM mytable m
JOIN q
ON m.parentID = q.PersonID
)
SELECT *
FROM q
WHERE HasSubordinate = 0
非常感谢任何帮助!!
答案 0 :(得分:1)
您可以在递归cte中添加一个新字段,并在迭代时加倍:
WITH q AS
(
SELECT *,Quantity AS Tot_Qty
FROM mytable
WHERE PersonID = 1
UNION ALL
SELECT m.*,m.Quantity * q.Tot_Qty AS Tot_Qty
FROM mytable m
JOIN q
ON m.parentID = q.PersonID
)
SELECT *
FROM q
WHERE HasSubordinate = 0
注意:由于您使用的是2 x 1 x 1
,因此2 x 1 x 1 x 1
不会ParentID
。
答案 1 :(得分:0)
每隔一段时间,有人会抱怨没有MULT
聚合函数。也许有一天会有,但在那之前,我们必须作弊。以下是基于LOG(a * b * c)= LOG(a)+ LOG(b)+ LOG(c)的事实。不幸的是,它需要一个额外的CTE级别(尽管不是递归的)但最终会得到一个答案。
with
List( PersonID, Initials, ParentID, Qty )as(
select 1, 'CJ', null, 1 union all
select 2, 'EB', 1, 2 union all
select 3, 'MB', 1, 3 union all
select 4, 'SW', 2, 4 union all
select 5, 'YT', null, 2 union all
select 6, 'IS', 5, 5
),
CTE( PersonID, Initials, ParentID, Qty, Root )as(
select l.PersonID, l.Initials, l.ParentID, l.Qty, l.PersonID
from List l
where l.ParentID is null
--and l.Initials = 'CJ'
union all
select l.PersonID, l.Initials, l.ParentID, l.Qty, c.Root
from CTE c
join List l
on l.ParentID = c.PersonID
),
Logs( PersonID, Initials, ParentID, Qty, Root, SumLog )as(
select *, sum( log( Qty )) over( partition by Root)
from CTE
)
select *, exp( SumLog ) as Mult
from Logs
order by PersonID;
生成此结果:
PersonID Initials ParentID Qty Root SumLog Mult
-------- -------- -------- --- ---- ---------------- ----
1 CJ NULL 1 1 3.17805383034795 24
2 EB 1 2 1 3.17805383034795 24
3 MB 1 3 1 3.17805383034795 24
4 SW 2 4 1 3.17805383034795 24
5 YT NULL 2 5 2.30258509299405 10
6 IS 5 5 5 2.30258509299405 10
这满足了所述的要求,拉最后一行将使所有数量的总和相乘 - 它们都具有该值。也许聪明的人可以产生一个总计。我会把它作为一种练习(意思是我懒得自己尝试)。