Sql 对Rails使用includes()而不是joins()

Sql 对Rails使用includes()而不是joins(),sql,ruby-on-rails,Sql,Ruby On Rails,我有两种型号发票和付款人。它们之间的关系是invoice有许多payevents 我使用以下查询获取所有已全额支付的账单: Invoice.joins(:payevents).group("invoice.id").having("sum(payevents.amount) >= invoice.amount") 这个查询工作正常。但是,它不是最优的,因为结果不包括payevents。我尝试使用包含而不是连接,但不起作用 Invoice.includes(:payevents).grou

我有两种型号
发票
付款人
。它们之间的关系是
invoice
有许多
payevents

我使用以下查询获取所有已全额支付的账单:

Invoice.joins(:payevents).group("invoice.id").having("sum(payevents.amount) >= invoice.amount")
这个查询工作正常。但是,它不是最优的,因为结果不包括
payevents
。我尝试使用
包含
而不是
连接
,但不起作用

Invoice.includes(:payevents).group("invoice.id").having("sum(payevents.amount) >= invoice.amount")
错误是

ActiveRecord::StatementInvalid: PG::GroupingError: ERROR:  column "payevents.id" must appear in the GROUP BY clause or be used in an aggregate function
你知道这里怎么了吗


如果我正确理解您的意思,我将使用PostgreSQL和Rails 4.1,您应该使用subquery。像这样:

subquery = Invoice.joins(:payevents)
                  .group("invoice.id")
                  .having("sum(payevents.amount) >= invoice.amount")
                  .select("invoice.id id, sum(payevents.amount) amount").to_sql

query = Invoice.includes(:payevents).joins("JOIN (#{subquery}) subquery ON invoice.id = subquery.id")

因此,您将拥有发票、聚合金额、子查询的内部联接过滤结果和所有PayeEvents字段。

更简单的解决方案是显式使用预加载

Invoice.joins(:payevents).group("invoice.id").having("sum(payevents.amount) >= invoice.amount").preload(:payevents)

我认为您可以通过
选择('invoice.id,sum(payevents.amount)
明确定义所需的字段。让我知道它是否有效我写它作为回答你能描述一下你想要在输出中哪些字段吗?
包含
联接
之间的区别在于
包含
左联接和
联接
=
内部联接
我需要结果中Invoice和Payevents的所有列,以防止在我的视图中循环原始
联接
结果时出现数百个附加查询。这很有效。但是,
包含(:payevents)
必须放在
联接之前