我尝试在PostgreSQL数据库中处理这种情况。我通过编程将数据插入到名为“发票”的表中:
invoice_id account_id amount current
1 a2322 3 null
2 a2322 10 null
3 b4354 1 null
4 c8099 2 null
5 a2322 4 null
6 b4354 -5 null
因此,当插入新记录时,我想用这样的总和来更新current
字段:
invoice_id account_id amount current
1 a2322 3 null
2 a2322 10 null
3 b4354 1 null
4 c8099 2 null
5 a2322 4 null
6 b4354 -5 null
7 a2322 4 result(sum of amount: 21)
8 b4354 3 result(sum of amount: -1)
我可以在PostgreSQL内不用编程吗?
答案 0 :(得分:2)
您可以在运行AFTER INSERT OR UPDATE OR DELETE
的触发器FOR EACH STATEMENT
中进行此操作。即使不在客户端,这也是编程。
在触发器中,您可以像这样计算总和(假设invoice_id
是serial
):
INSERT INTO invoice
(account_id, amount, current)
SELECT account_id, sum(amount), 'result'
FROM invoice
WHERE current IS NULL
GROUP BY account_id
HAVING count(*) > 1
ON CONFLICT (account_id, current)
DO UPDATE
SET amount = EXCLUDED.amount;
这需要在UNIQUE
上使用(account_id, current)
约束,并利用了这样的事实:只要不包含NULL,唯一约束就允许“重复”。
答案 1 :(得分:0)
从技术上讲,这不是您问题的直接答案。但是,您想要的是流水号。您可能不需要存储该信息。可以即时计算:
SELECT *, SUM(amount) OVER(ORDER BY invoice_id) AS running_total;
这样,您就不必担心对帐和/或更新错误。特别是如果以后需要更新数量时,运行总计将被SUM()OVER()弄乱,它将始终保持一致。