在我的应用程序中,Invoice has_many item_numbers
并且Invoice has_many payments
. 每张发票都有一个余额,它是 ItemNumber 金额属性的总和,减去 Payment amount 属性的总和。
余额在发票模型中很容易计算,但我正在尝试编写一个按余额对发票进行排序的查询,而这在 ActiveRecord/SQL 中更难做到。
我已成功通过以下查询订购了 item_numbers 总数的发票(感谢 Daniel Rikowski):
Invoice.where(user_id: 1, deleted: false, status: 'Sent')
.joins(:item_numbers)
.select('invoices.*, sum(item_numbers.amount)')
.group('invoices.id')
.order('sum(item_numbers.amount) asc')
.limit(20)
我试图通过以下余额将其扩展到订单;
Invoice.where(user_id: 1, deleted: false, status: 'Sent')
.joins(:item_numbers)
.joins("FULL OUTER JOIN payments ON payments.invoice_id = invoices.id")
.select("invoices.*, sum(item_numbers.amount_with_gst) - COALESCE(sum(payments.amount), 0)")
.group("invoices.id")
.order("sum(item_numbers.amount_with_gst) - COALESCE(sum(payments.amount), 0) #{dir}")/
这个查询有两个问题。首先,它非常丑陋,其次,它不起作用。我在付款表上使用了完整的外部联接,因为并非所有发票都有付款,如果我只使用 joins(:payments) 任何没有付款的发票,都会从结果中排除。COALESCE 被放置在那里以处理空金额。
查询接近,但假设有 3 个 item_numbers 和 1 个付款(非常典型的场景),付款金额将被减去 3 次,导致余额远低于实际金额(通常为负余额)。
我可能很清楚我的深度。我在这个查询中付出了很多努力(大约 4 小时的阅读和失败的尝试)并且不能完全确定它。我的数据库是 PostgreSQL。