我有一张这样的桌子:
id activity pay parent
1 pay all - null
2 pay tax 10 $ 1
3 pay water bills - 1
4 fix house - null
5 fix roof 1 $ 4
6 pay drinking water 1 $ 3 我希望得到这样的表:
id activity pay parent matriks
1 pay all {11 $} null 1 (pay tax + pay water bills)
2 pay tax 10 $ 1 1-2
3 pay water bills {1 $} 1 1-3 (pay drinking water)
4 fix house {1 $} null 4 (fix roof)
5 fix roof 1 $ 4 4-5
6 pay drinking water 1 $ 3 1-3-6从孩子到父母的计数:问题是当饮用水中的水费没有计算在内时,如果交税或交水没有支付价值,则支付所有无法计算的费用。
发布于 2015-07-21 17:49:12
我在我们的postgres db (版本8.4.22)上尝试了一下,因为小提琴对我来说有点慢。但是SQL可以粘贴到那里,它可以在postgres上工作。
这里仍然是fiddle demo第一次花了大约20秒,但后来更快。
下面是为我生成计算结果的内容。(我没有根据您的要求对其进行格式化,因为在我看来,主要练习就是计算。)这里假设您的表名为activity
with recursive rekmatriks as(
select id, activity, pay, parent, id::text as matriks, 0 as lev
from activity
where parent is null
union all
select activity.id, activity.activity, activity.pay, activity.parent,
rekmatriks.matriks || '-' || activity.id::text as matriks,
rekmatriks.lev+1 as lev
from activity inner join rekmatriks on activity.parent = rekmatriks.id
)
, reksum as (
select id, activity, pay, parent, matriks, lev, coalesce(pay,0) as subsum
from rekmatriks
where not exists(select id from rekmatriks rmi where rmi.parent=rekmatriks.id)
union all
select rekmatriks.*, reksum.subsum+coalesce(rekmatriks.pay, 0) as subsum
from rekmatriks inner join reksum on rekmatriks.id = reksum.parent)
select id, activity, pay, parent, matriks, sum(subsum) as amount, lev
from reksum
group by id, activity, pay, parent, matriks, lev
order by id作为额外的好处,这提供了id的嵌套深度。0表示父级,1表示第一个子级,等等。这使用两个递归WITH queries来实现您想要的。所需的计算值位于amount列中。
第一个(rekmatriks)从上到下处理表中的IDs,从父ids为NULL的所有ids开始。递归部分只是简单地获取父id,并将它自己的id添加到它,以获得您的矩阵树表示字段。
第二个(reksum)从下到上工作,从没有子元素的所有行开始。该查询的递归部分为在非递归部分中选择的每个子行选择一个父行,并计算每行的pay和subsum之和。这将为每个id生成多个行,因为一个父对象可以有多个子对象。
现在只剩下最后一条select语句了。它使用GROUP BY和SUM将多个可能的子求和值聚合到一行中。
这确实适用于您的特定示例。如果样本数据中没有显示不同的情况,那么它可能会失败,例如,如果具有子项的项带有需要添加的值。
https://stackoverflow.com/questions/31530061
复制相似问题