"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_total
和 total_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
我的目标是生成一个包含每个客户及其余额的 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_total
和 total_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