【发布时间】:2012-12-16 01:51:45
【问题描述】:
在我的应用程序中,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。
【问题讨论】:
标签: sql ruby-on-rails postgresql activerecord join