我想使用原始sql计算帐户余额,而无需额外的应用程序逻辑。 事务架构包括amount,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
我的余额查询中错过了什么?
答案 0 :(得分:4)
您基本上是在计算tdebits
和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
。
答案 1 :(得分: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;