Postgresql Postgres中两个表中带和的递归查询
我有2个表,我需要制作一个带有分页(限制和偏移)的筛选器:Postgresql Postgres中两个表中带和的递归查询,postgresql,sum,recursive-query,Postgresql,Sum,Recursive Query,我有2个表,我需要制作一个带有分页(限制和偏移)的筛选器: res_合作伙伴(id、姓名、家长id)(25万行) 账户发票(id、未征税金额、合作伙伴id、创建日期)(700k行) 一个合作伙伴可以有多个子项和多个帐户发票 我需要在一个时间段内获取所有客户及其子女关联的总发票(未征税金额的总和)。 例如: res\u合作伙伴 id --- name --- parent_id 1 --- Jon 2 --- Snow ---- 1 3 --- Sam
id --- name --- parent_id
1 --- Jon
2 --- Snow ---- 1
3 --- Sam ----- 2
账户\发票
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
您可以使用递归存储过程来计算每个记录的值 id | fntree -: | -----: 1 | 24.00 2 | 10.00 3 | 3.00
dbfiddle这里是一种使用单个SQL查询的方法,它使用递归的
、整数数组、包含运算符(发布您为解决此问题而编写的任何代码。您做了哪些努力?哪里有问题?在这里使用plpgsql没有意义:-)您是用纯SQL编写的,因此函数(如果需要的话),可以是语言sql
。我很乐意帮忙
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
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;