"has many through" 关系上的 PSQL 查询求和列产生重复项

PSQL Query summing columns on a "has many through" relationship yielding duplicates

我的目标是生成一个包含每个客户及其余额的 ActiveRecordRelation (sale_line_items.total + sale_adjustments.effect_to_balance - sale_payment.amount)

class Customer < ActiveRecord:Base
  has_many :sales

class Sale < ActiveRecord:Base
  belongs_to :customer
  has_many :sale_adjustments
  has_many :sale_payments

class SaleLineItem < ActiveRecord:Base
  belongs_to :sale

class SalePayment < ActiveRecord:Base
  belongs_to :sale

class SaleAdjustment < ActiveRecord:Base
  belongs_to :sale 

我当前的代码:

customers = Customer.all

customers = customers.joins("LEFT OUTER JOIN sales ON customers.id = sales.customer_id")
    customers = customers.joins("LEFT OUTER JOIN sale_line_items ON sale_line_items.sale_id = sales.id")
    customers = customers.joins("LEFT OUTER JOIN sale_adjustments ON sale_adjustments.sale_id = sales.id")
    customers = customers.joins("LEFT OUTER JOIN sale_payments ON sale_payments.sale_id = sales.id")
customers = customers.select("customers.*,
    COALESCE(SUM(sale_line_items.total),0) +
    COALESCE(SUM(sale_adjustments.effect_to_balance),0) -
    COALESCE(SUM(sale_payments.amount),0) AS customer_balance")
customers.group("customers.id").distinct 

问题在于,如果有不止一次付款或调整,则结果中的行项目会重复 table,本质上是将总数增加一个因子。我想我的理解足以识别问题,但还不足以提出解决方案。 rails 生成的查询如下。

[1m[36mCustomer Load (2.2ms)[0m  [1mSELECT DISTINCT customers.*,
    COALESCE(SUM(sale_line_items.total),0) +
    COALESCE(SUM(sale_adjustments.effect_to_balance),0) -
    COALESCE(SUM(sale_payments.amount),0) AS customer_balance 
    FROM "customers" LEFT OUTER JOIN sales ON customers.id = sales.customer_id
    LEFT OUTER JOIN sale_line_items ON sale_line_items.sale_id = sales.id
    LEFT OUTER JOIN sale_adjustments ON sale_adjustments.sale_id = sales.id
    LEFT OUTER JOIN sale_payments ON sale_payments.sale_id = sales.id 
    WHERE "customers"."business_id" =  GROUP BY customers.id[0m  [["business_id", "bd0c474c-db6e-43bc-95ca-90541d3840d1"]]

错误示例如下: 一位客户的一笔销售中有一个 50 美元的订单项

total sales: , balance: 

添加一笔 10 美元的付款

total sales: , balance: 

第二次付款时出现问题,假设 1 美元

total sales 0, balance 

这笔额外付款会为订单项创建一个重复行。第三次付款将达到 150 美元,依此类推...

非常感谢任何帮助 - 我整晚都在做这件事,现在我只是在兜圈子。

我在计算 PHP-MySQL 项目的发票余额时也做过类似的事情。我最终改变了我的数据库结构和应用程序流程。我修改了发票 table 以包含 invoice_totaltotal_payment 列,这些列将随着发票和付款模块的创建和编辑而更新。

尽管您可以使用 sub-queries 来获得所需的结果,例如:

SELECT DISTINCT customers.*,
COALESCE(SUM(sli.total),0) +
COALESCE(SUM(sa.effect_to_balance),0) -
COALESCE(SUM(sp.amount),0) AS customer_balance 
FROM "customers" LEFT OUTER JOIN sales ON customers.id = sales.customer_id
LEFT OUTER JOIN (SELECT sale_id, SUM(total) total FROM sale_line_items) sli ON sli.sale_id = sales.id
LEFT OUTER JOIN (SELECT sale_id, SUM(effect_to_balance) effect_to_balance FROM sale_adjustments) sa ON sa.sale_id = sales.id
LEFT OUTER JOIN (SELECT sale_id, SUM(amount) amountFROM sale_payments) sp ON sp.sale_id = sales.id 
WHERE "customers"."business_id" =  GROUP BY customers.id

希望这能解决您的问题:)

rails 代码仿照 Manoj Monga 的回答:

customers = Customer.all

customers = customers.joins("LEFT OUTER JOIN sales ON customers.id = sales.customer_id")

customers = customers.joins("LEFT OUTER JOIN (SELECT sale_id, SUM(total) total FROM sale_line_items GROUP BY sale_id) sli ON sli.sale_id = sales.id")
customers = customers.joins("LEFT OUTER JOIN (SELECT sale_id, SUM(effect_to_balance) effect_to_balance FROM sale_adjustments GROUP BY sale_id) sa ON sa.sale_id = sales.id")
customers = customers.joins("LEFT OUTER JOIN (SELECT sale_id, SUM(amount) amount FROM sale_payments GROUP BY sale_id) sp ON sp.sale_id = sales.id")

customers = customers.select("customers.*,
    COALESCE(SUM(total), 0) as sales_total,
    COALESCE(SUM(total), 0) + 
    COALESCE(SUM(effect_to_balance),0) - 
    COALESCE(SUM(amount),0) AS customer_balance")
customers.group("customers.id").distinct