如何使用ROOM框架格式化SQL查询语句以计算收支差额
解决你的SQL余额计算问题
你的原始查询存在语法错误——不能把多个SELECT语句用逗号直接拼接,而且也没法在同一个SELECT里直接引用前面定义的别名(比如INCOME和EXPENSE)。不过不用新增数据表列,我们可以用更简洁高效的SQL语句搞定这个需求,下面给你两种可行的方案:
方案一:条件求和(推荐,效率最高)
这种方法只需要扫描一次数据表,用CASE WHEN分别计算收入、支出和余额,是最优解:
SELECT SUM(CASE WHEN isExpense = 0 THEN amount ELSE 0 END) AS INCOME, SUM(CASE WHEN isExpense = 1 THEN amount ELSE 0 END) AS EXPENSE, SUM(CASE WHEN isExpense = 0 THEN amount ELSE -amount END) AS BALANCE FROM `transaction`
逻辑说明:
- 遇到
isExpense=0(收入)的记录,把amount加入收入总和,支出部分记为0; - 遇到
isExpense=1(支出)的记录,把amount加入支出总和,收入部分记为0; - 余额直接通过「收入金额 - 支出金额」的逻辑计算,也就是把支出的
amount转为负数后求和。
如果你的函数只需要返回余额(不需要单独的收入和支出总和),可以简化成:
@Query(""" SELECT SUM(CASE WHEN isExpense = 0 THEN amount ELSE -amount END) AS BALANCE FROM `transaction` """) fun getTotalBalance(): Flow<Double?>
方案二:子查询作为列
这种方法用子查询分别计算收入和支出,再计算余额,虽然逻辑直观,但会扫描三次数据表,效率不如方案一:
SELECT (SELECT SUM(amount) FROM `transaction` WHERE isExpense = 0) AS INCOME, (SELECT SUM(amount) FROM `transaction` WHERE isExpense = 1) AS EXPENSE, (SELECT SUM(amount) FROM `transaction` WHERE isExpense = 0) - (SELECT SUM(amount) FROM `transaction` WHERE isExpense = 1) AS BALANCE FROM `transaction` LIMIT 1
注意这里要加LIMIT 1,避免因为数据表有N条记录就返回N行重复的结果。
完全不需要新增数据表列,用上面的SQL就能直接得到你想要的余额结果啦。
内容的提问来源于stack exchange,提问作者Decline
相关产品推荐
相关产品推荐

