You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails4如何实现嵌套关联查询(contributions内连deposits左外连)并求和

实现方案

Rails 4 没有内置的left_outer_joins链式方法,你可以通过给joins方法传入原生SQL片段自定义连接规则,同时配合聚合函数完成需求,完整实现代码如下:

# 查询所有有contribution的Saving,计算关联的deposit总额,保留无deposit的记录
savings_with_total = Saving.select("savings.*, COALESCE(SUM(deposits.amount), 0) AS total_deposit_amount")
  .joins("INNER JOIN contributions ON contributions.saving_id = savings.id")
  .joins("LEFT OUTER JOIN deposits ON deposits.contribution_id = contributions.id")
  .group("savings.id")

代码说明

  • select部分除了加载Saving的全量字段,通过SUM(deposits.amount)计算存款总额,再用COALESCE函数把无存款记录的空值转换为0,避免出现nil结果
  • 第一个joins写INNER JOIN逻辑关联contributions,符合你要求的「只保留存在contribution的Saving」的规则
  • 第二个joins写LEFT OUTER JOIN逻辑关联deposits,即使对应的contribution没有关联任何deposit,记录也不会被过滤
  • 最后按savings.id分组,保证每个Saving对应一条统计结果

额外优化

如果你后续需要遍历查询结果的关联contributions和deposits,为了避免N+1查询问题,可以在查询链上追加includes方法预加载关联数据:

savings_with_total = Saving.select("savings.*, COALESCE(SUM(deposits.amount), 0) AS total_deposit_amount")
  .joins("INNER JOIN contributions ON contributions.saving_id = savings.id")
  .joins("LEFT OUTER JOIN deposits ON deposits.contribution_id = contributions.id")
  .includes(contributions: :deposits)
  .group("savings.id")

使用方式

查询得到的Saving对象可以直接调用动态生成的total_deposit_amount属性获取存款总和:

savings_with_total.each do |saving|
  puts "储蓄计划#{saving.id}的总存款额:#{saving.total_deposit_amount}"
end

内容的提问来源于stack exchange,提问作者Suganya Selvarajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 19:27:00