我有3个关联:
Invoice
has_many :invoice_items
has_many :items, through: :invoice_items
InvoiceItem
belongs_to :invoice
belongs_to :item
Item
has_many :invoice_items
has_many :invoices, through: :invoice_items
我要写一个报告,选择所有同时具有item_id 1和item_id 2的InvoiceItem的发票
我可以用Ruby做到这一点。
invoices = Invoice.joins(:invoice_items).where(item_id: [1, 2])
invoices.each do |invoice|
if ([1,2] - invoice_items.pluck(:item_id).uniq).empty?
@real_invoices << invoice
end
end
但是对于数百万条记录,这是完全不可行的。
我尝试过:
Invoice.joins(:invoice_items).having('COUNT(CASE WHEN invoice_items.item_id IN (?) THEN 1 END) = ?',[1,2], [1,2].length).group(:id)
但这不会产生正确的结果。
答案 0 :(得分:0)
也许您可以在此处尝试使用子查询。可以按照以下步骤进行:
1)选择invoice_items.invoice_id
为1的invoice_items.item_id
2)在invoice_items.invoice_id
为2的情况下选择invoice_items.item_id
3)将这两个查询的结果相交以获得两个都通用的发票ID
4)使用这些ID提取发票
Invoice.where("
invoices.id IN
(
SELECT invoice_items.invoice_id
FROM invoice_items
WHERE invoice_items.item_id = 1
INTERSECT
SELECT invoice_items.invoice_id
FROM invoice_items
WHERE invoice_items.item_id = 2
)
")
这将通过使用来自invoice_items
关系的信息来防止联接,但是会进行多个子查询。但是,您从应用程序对DB的调用将是一个。