递归计数sql
我有这样的桌子:递归计数sql,sql,postgresql,recursion,count,Sql,Postgresql,Recursion,Count,我有这样的桌子: id activity pay parent 1 pay all - null 2 pay tax 10 $ 1 3 pay water bills - 1 4 fix house - null 5 fix r
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
我想要这样的桌子:
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
从子项到父项的计数:
问题是,当水费账单没有从饮用水算起时,如果交税或付水费没有支付价值,则“支付全部”无法计算。我在我们的postgres db(版本8.4.22)上尝试了这一点,因为小提琴对我来说有点慢。但是SQL可以粘贴在那里,它可以为postgres工作 还是第一次需要20秒的时间,但之后会更快 下面是为我生成计算结果的内容。(我没有按照您的要求设置格式,因为我认为主要的练习是计算。)这假设您的表被称为
活动:
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,等等。这使用两个递归来实现您想要的。您需要的计算值位于金额
列中
第一个(rekmatriks
)从上到下处理表中的ID,从父项为NULL
的任何ID开始。递归部分只是获取父id并将其自身的id添加到其中,以实现矩阵树表示字段
第二个(reksum
)自下而上工作,从没有子元素的所有行开始。此查询的递归部分为在非递归部分中选择的每个子行选择父行,并计算每行的pay
和subsum
之和。这会为每个id生成多行,因为一个父级可以有多个子级
现在只剩下最后的select语句。它使用groupby
和SUM
将多个可能的子总和值聚合到一行中
这确实适用于您的特定示例。如果示例数据中没有显示不同的情况,例如,如果有子项的项带有需要添加的值,则可能会失败。当您说table时,是指db还是php?如果是db,您使用的是什么RDBMS?那些是什么?什么是矩阵?你的逻辑是什么?@jWeaver在支付饮用水的情况下1-3-6
我想是因为添加到行1、3和6
-支付所有,支付水,支付饮用水
它就像6的父母是3,3的父母是1,所以1-3-6,他应该使用1->3->6clarity@JuanCarlosOropeza我使用postgre,{}孩子的价值,这在右表中解释,例如:支付水费,它让孩子支付饮用水,价值1美元,它对它的父母(支付水费)很好。唯一的问题是格式,不知道OP是否严格按照{10$}
和1(纳税+水费账单)
的方式支付,太好了,这就解决了我的问题!!谢谢大家,谢谢@takrl