[英]Sum on a Recursive Self-Join
我在以下位置找到了一篇非常有用的文章: 在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
任何帮助是极大的赞赏!!
您可以向递归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
。
有时,有人抱怨没有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
这样就满足了上述要求,将最后一行的所有QTY总数相乘即可,它们都具有该值。 也许某个聪明的人可以产生一个连续的总数。 我将其保留为练习(这意味着我懒得自己尝试一下)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.