获取列值与其之前所有行数据的差异
Get the difference for a column value by all its previous rows data
请考虑以下两个表格:
保险库
- id BIGSERIAL 主键
- 名称 VARCHAR(30) NOT NULL
交易
- id BIGSERIAL 主键
- transaction_type VARCHAR(6) NOT NULL -- 在“贷方”或“借方”之间选择
- 金额 NUMERIC(15,6) NOT NULL
- vault_id BIGINT 引用库 (id)
在获取交易row/s时,我想在交易完成后为剩余金库余额获取一个额外的列。
交易示例:
id transaction_type amount vault_id vault_balance
1 credit 100 1 100 // since there was no prev transaction for this vault
5 credit 400 1 500
12 debit 200 1 300
20 credit 100 1 400
我可以添加一列来保存金库余额并将其用于下一次交易。但是假设用户删除了一行,例如删除了信用额度为 400 的行 id 5。那么其后续交易金库余额应相应变化。因此,对于第 12 行,保险库余额将为 -100,行 ID 20 的保险库余额将为 0。
id transaction_type amount vault_id vault_balance
1 credit 100 1 100 // since there was no prev transaction for this vault
12 debit 200 1 -100
20 credit 100 1 0
我的看法有两种:
- 添加一列来存储交易中的金库余额,如果有变化,则其所有后续交易的金库余额都应相应更新。
- 也许有一种方法可以得到所有以前和当前交易金额之间的贷方和借方差额。
但我希望有更好的方法?你能帮我处理这种情况的最有效方法是什么吗?
更新
Link 到 Table fiddle.
有更好的方法,至少恕我直言。不要更改您的 table 定义,而是在具有 运行 余额的事务上创建一个 view
,并且该列是在视图中派生的。
create view transactions_with_bal as
select id
, transaction_type
, amount
, vault_id
, sum(amount * case when transaction_type = 'credit' then 1 else -1 end )
over (partition by vault_id order by id) balance
from transactions;
现在您不需要对 table 进行任何额外的 DML 处理(删除、插入、更新);没有触发器,没有额外的代码,什么都没有。当多个用户同时针对它发出 DML 时,您也可以避免竞争条件。它甚至可以处理 vault_id
列发生变化的情况。
请考虑以下两个表格:
保险库
- id BIGSERIAL 主键
- 名称 VARCHAR(30) NOT NULL
交易
- id BIGSERIAL 主键
- transaction_type VARCHAR(6) NOT NULL -- 在“贷方”或“借方”之间选择
- 金额 NUMERIC(15,6) NOT NULL
- vault_id BIGINT 引用库 (id)
在获取交易row/s时,我想在交易完成后为剩余金库余额获取一个额外的列。
交易示例:
id transaction_type amount vault_id vault_balance
1 credit 100 1 100 // since there was no prev transaction for this vault
5 credit 400 1 500
12 debit 200 1 300
20 credit 100 1 400
我可以添加一列来保存金库余额并将其用于下一次交易。但是假设用户删除了一行,例如删除了信用额度为 400 的行 id 5。那么其后续交易金库余额应相应变化。因此,对于第 12 行,保险库余额将为 -100,行 ID 20 的保险库余额将为 0。
id transaction_type amount vault_id vault_balance
1 credit 100 1 100 // since there was no prev transaction for this vault
12 debit 200 1 -100
20 credit 100 1 0
我的看法有两种:
- 添加一列来存储交易中的金库余额,如果有变化,则其所有后续交易的金库余额都应相应更新。
- 也许有一种方法可以得到所有以前和当前交易金额之间的贷方和借方差额。
但我希望有更好的方法?你能帮我处理这种情况的最有效方法是什么吗?
更新
Link 到 Table fiddle.
有更好的方法,至少恕我直言。不要更改您的 table 定义,而是在具有 运行 余额的事务上创建一个 view
,并且该列是在视图中派生的。
create view transactions_with_bal as
select id
, transaction_type
, amount
, vault_id
, sum(amount * case when transaction_type = 'credit' then 1 else -1 end )
over (partition by vault_id order by id) balance
from transactions;
现在您不需要对 table 进行任何额外的 DML 处理(删除、插入、更新);没有触发器,没有额外的代码,什么都没有。当多个用户同时针对它发出 DML 时,您也可以避免竞争条件。它甚至可以处理 vault_id
列发生变化的情况。