我有2个表,我需要制作一个带分页(限制和偏移)的过滤器:
一个合作伙伴可以有很多孩子,还有很多帐户发票。
我需要让所有客户和总发票(amount_untaxed的总和)在一段时间内与他和他们的孩子相关联。 例如:
res_partner
id --- name --- parent_id
1 --- Jon
2 --- Snow ---- 1
3 --- Sam ----- 2
account_invoice
id --- amount_untaxed --- partner_id --- created_date
1 ------------------ 5.00 ---------1--------------'2015-09-29 21:37:39.427189'
2 ------------------ 7.00 ---------2--------------'2015-09-29 21:37:39.427189'
3 ------------------ 3.00 ---------3--------------'2015-09-29 21:37:39.427189'
4 ------------------ 9.00 ---------1--------------'2015-09-29 21:37:39.427189'
我希望得到:
res_partner --- amount
1 -----------------24
2 -----------------10
3 -----------------3
答案 0 :(得分:1)
您可以使用递归存储过程来计算每条记录的值。
CREATE OR REPLACE FUNCTION fnTree(pid int) RETURNS numeric AS $$ DECLARE total numeric; BEGIN WITH RECURSIVE tree(id, parent_id) AS ( SELECT id, parent_id FROM res_partner WHERE id = pid UNION ALL SELECT rp.id, rp.parent_id FROM res_partner rp JOIN tree ON rp.parent_id = tree.id ) SELECT sum(amount_untaxed) into total FROM account_invoice ai WHERE partner_id in (SELECT id FROM tree); RETURN total; END; $$ LANGUAGE plpgsql;
✓
select id, fnTree(id) from res_partner;
id | fntree -: | -----: 1 | 24.00 2 | 10.00 3 | 3.00
dbfiddle here
答案 1 :(得分:0)
以下是单一SQL查询的方法,它使用WITH RECURSIVE
,整数数组,包含运算符(<@
),数组连接运算符(||
)和转换的函数结果集的数组unnest()
。
在WITH RECURSIVE
内,我们建立&#34;路径&#34;对于每条记录,然后计算金额总和:
with recursive res(id, name, parent_id, path) as (
select id, name, parent_id, array[id]
from res_partner
where parent_id is null
union all
select
r2.id, r2.name, r2.parent_id, array[r2.id] || res.path
from res_partner r2
join res on res.id = r2.parent_id
)
select
id as res_partner,
--path, -- uncomment to debug
(
select sum(amount_untaxed)
from account_invoice
where
partner_id in (
select id
from res r_in
where r_out.path <@ r_in.path
)
) as amount
from res r_out;