我有两个模型invoice
和payments
。它们之间的关系为invoice
has_many payments
。
我使用以下左外联接返回所有尚未支付的发票:
result1 = Invoice.includes(:payments).where(:payments => { :id => nil })
我也对所有已部分支付的发票感兴趣。要返回那些我使用内连接:
result2 = Invoice.joins(:payments).group("transfers.id").having("sum(payments.amount) < invoice.amount")
我现在想结合两个结果,即我希望所有未支付或未全额支付的发票。我知道我可以做result = result1 + result2
。但是,这不会返回ActiveRecord对象。有没有办法在单个查询中组合这两个查询?
我使用Rails 4.1和PostgreSQL
答案 0 :(得分:3)
我相信你是正确的,你不能让ActiveRecord生成除了内连接之外的任何东西而不用自己编写它。但我不会在此上下文中使用includes
,因为它确实会导致ActiveRecord生成不同的连接,即“实现细节” - 它的基本目的是加载相关的模型,不一定是你想要的。
在您提出的解决方案中,我不明白您为什么要将invoices.id
和payments.id
分组 - 这似乎打败了分组的目的。
你可以做类似下面的事情,虽然我不能说这似乎更像是Rails-ish。
Invoice.joins("LEFT JOIN payments ON payments.transfer_id = invoices.id")
.select("invoices.id, SUM(payments.amount) AS total_paid")
.group("invoices.id")
.having("SUM(payments.amount) IS NULL OR SUM(payments.amount) < invoices.amount")
这将返回仅包含id
字段和total_paid
字段集的Invoice对象列表。如果您需要其他可用字段,请将它们添加到select
语句和group
语句中。
答案 1 :(得分:0)
我最后只做了LEFT OUTER JOIN。但是,Rails似乎不支持group
和having
由includes()
生成的LEFT OUTER JOIN。因此,我必须手动构建连接,这实际上并不像Rails方式那样&#34;。
我的查询:
Invoice.joins("LEFT JOIN payments ON payments.transfer_id = invoices.id").group("invoices.id, payments.id").having("((payments.id IS NULL) OR (sum(payments.amount) < invoices.amount))")
更新:这不会按预期工作。请参阅接受的答案。