0

我想使用原始 sql 计算帐户余额,而无需额外的应用程序逻辑。交易模式包括金额、from_account_id 和 to_account_id

我的查询是

SELECT SUM(tdebit.amount) - SUM(tcredit.amount) as balance
FROM accounts as a
INNER JOIN transactions as tdebit ON a.id = tdebit.to_account_id
INNER JOIN transactions as tcredit ON a.id = tcredit.from_account_id
WHERE a.id = $1 AND tdebit.succeed = true AND tcredit.succeed = true

而且它没有像我预期的那样工作 - 结果是错误的,但是如果我只在它正常工作后才加入交易,例如借记金额就可以了

SELECT SUM(tdebit.amount) as debit
FROM accounts as a
INNER JOIN transactions as tdebit ON a.id = tdebit.to_account_id
WHERE a.id = $1 AND tdebit.succeed = true

我在余额查询中遗漏了什么?

http://sqlfiddle.com/#!15/b5565/1

4

2 回答 2

4

您基本上是在计算 atdebits和之间的叉积tcredits,即对于您中的每一行,tdebits您都在遍历tcredits. 也没有理由加入accounts(除非to_account_id并且from_account_id不是外键)。

您只需要对交易进行一次传递,您只需要知道该金额是贷记还是借记。

SELECT SUM(CASE WHEN t.to_account_id = $1 THEN t.amount ELSE -t.amount END) AS amount
FROM transactions AS t
WHERE (t.to_account_id = $1 OR t.from_account_id = $1)
  AND t.succeed = true

如果一个帐户可以转移到自己,添加一个t.to_account_id <> t.from_account_id.

于 2016-01-30T13:16:35.220 回答
1

如果您想要所有帐户的值,请在进行连接之前进行聚合:

select a.*, coalesce(tdebit.debit, 0) - coalesce(tcredit.credit, 0)
from accounts a left join
     (select t.to_account_id, sum(t.amount) as debit
      from transactions t
      group by t.to_account_id
     ) tdebit
     on a.id = tdebit.to_account_id left join
     (select t.from_account_id, sum(t.amount) as credit
      from transactions t
      group by t.from_account_id
     ) tcredit
     on a.id = tcredit.from_account_id;
于 2016-01-30T13:16:52.363 回答