【问题标题】:Selecting sum results from multiple tables in Rails从 Rails 中的多个表中选择总和结果
【发布时间】:2013-03-15 07:30:11
【问题描述】:

我在 Rails 控制台中工作。我想在两个不同的表中选择同名列的总和。

这是我的 ActiveRecord 代码:

Computer.joins(:services, :repairs)
.select("computers.id, SUM(services.cost) as SCOST, SUM(repairs.cost) as RCOST")
.group("computers.id")

这很好用,并返回以下正确的 SQL:

`SELECT computers.id, SUM(services.cost) as SCOST, SUM(repairs.cost) as RCOST 
FROM "computers" INNER JOIN "services" ON "services"."computer_id" = "computers"."id" 
INNER JOIN "repairs" ON "repairs"."computer_id" = "computers"."id" 
GROUP BY computers.id `

但它在 Rails 控制台中给出以下结果:

=> [#<Computer id: 36>, #<Computer id: 32>]

难道我也不能访问我的 SUM 值吗?我在 postgres 中运行了上述 SQL 查询,它给出了所需的输出。

任何帮助将不胜感激。

谢谢。

【问题讨论】:

  • 您应该仍然可以访问总和。我认为 AR 只显示返回的列名及其值的列表。如果您将该查询分配给computers,请尝试computers.first.SCOST
  • 我得到 NoMethodError: undefined method `SCOST'
  • 我打算建议缩小别名,但有人已经回答了。你能试试吗?
  • 我尝试简单地缩小别名,但这似乎对我的理解没有帮助。

标签: ruby-on-rails ruby-on-rails-3 postgresql activerecord


【解决方案1】:

Rails 控制台使用inspect 方法来显示对象内容。此方法不显示自定义字段的值。通过显式引用自定义属性的值,您将能够在控制台上打印它。

Computer.joins(:services, :repairs)
.select("computers.id, SUM(services.cost) as scost, SUM(repairs.cost) as rcost")
.group("computers.id").each do |c|
  puts c.scost
  puts c.rcost
end

编辑

基于评论的示例:

在你的控制器中创建一个成员变量:

@computers = Computer.joins(:services, :repairs)
.select("computers.id, SUM(services.cost) as scost, SUM(repairs.cost) as rcost")
.group("computers.id")

遍历视图中的变量

- @computers.each do |computer| 
  = computer.scost
  = computer.rcost

编辑2

您需要使用LEFT OUTER JOIN 来获取缺少维修或服务的计算机的值。

join_sql = "LEFT OUTER JOIN services ON services.computer_id = computers.id
            LEFT OUTER JOIN repairs ON repairs.computer_id = computers.id"
sum_sql  = "SUM(COALESCE(services.cost, 0)) as scost, 
            SUM(COALESCE(repairs.cost, 0)) as rcost"

@computers = Computer.joins(join_sql)
.select("computers.id, #{sum_sql}")
.group("computers.id")

【讨论】:

  • 哈里什做得很好。它打印出我期望的结果:47711.97 4121.95 25131.54 10606.5 =&gt; [#&lt;Computer id: 36&gt;, #&lt;Computer id: 32&gt;]
  • 如何从我的视图中的实例变量访问这些 SUM 值?
  • 谢谢哈里什。你的解决方案太棒了。作为后续,如果我的 SUM 结果之一没有返回任何行,则整个结果集返回 0 个结果。例如,如果我们有计算机服务条目但没有维修,则返回 0 行。我尝试将 COALESCE(SUM(services.cost),0) 作为 scost,但没有成功。有什么建议吗?
  • 更新答案看看。
  • 我相信更新的答案不能正常工作。例如,如果我们有一个值为 5 的服务记录,然后有两个值为 20 的维修记录,我得到的 rcost SUM 是正确的(40),但总成本加倍(值为 10)。我通过在修复中添加另一行(总共 3 行)进一步测试了这一点,修复的 SUM 是正确的,但服务现在增加了三倍。这意味着行数最少的表的 SUM 将乘以行数最多的表上的行数。这有意义吗?
【解决方案2】:

尝试如下,

@computer_list = Computer.joins(:services, :repairs).select("computers.id, SUM(services.cost) as SCOST, SUM(repairs.cost) as RCOST").group("computers.id")
@computer_list.last.SCOST

【讨论】:

  • 感谢您的帮助。我得到的结果是: NoMethodError: undefined method `SCOST' for #
猜你喜欢
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多