gpt4 book ai didi

sql - 多表发票SUM比较

转载 作者:行者123 更新时间:2023-12-04 02:09:05 26 4
gpt4 key购买 nike

假设我在 Rails 应用中有 3 个表:

发票

id  | customer_id  | employee_id  | notes
---------------------------------------------------------------
1 | 1 | 5 | An order with 2 items.
2 | 12 | 5 | An order with 1 item.
3 | 17 | 12 | An empty order.
4 | 17 | 12 | A brand new order.

invoice_items
id  | invoice_id  | price  | name
---------------------------------------------------------
1 | 1 | 5.35 | widget
2 | 1 | 7.25 | thingy
3 | 2 | 1.25 | smaller thingy
4 | 2 | 1.25 | another smaller thingy

invoice_payments
id  | invoice_id  | amount  | method      | notes
---------------------------------------------------------
1 | 1 | 4.85 | credit card | Not enough
2 | 1 | 1.25 | credit card | Still not enough
3 | 2 | 1.25 | check | Paid in full

这代表4个订单:

第一个有 2 个项目,总共 12.60。它有两次付款,总付款金额为 6.10。此订单已部分支付。

第二个只有一个项目和一个付款,两者合计 1.25。此订单已全额支付。

第三个订单没有商品或付款。这对我们很重要,有时我们会使用这种情况。它也被视为全额支付。

最终订单再次有一件商品,总共 1.25,但尚未付款。

现在我需要一个查询:

显示所有尚未全额付款的订单;也就是说,所有订单使得项目的总和大于付款的总和。

我可以在纯 sql 中做到这一点:
SELECT      invoices.*,
invoice_payment_amounts.amount_paid AS amount_paid,
invoice_item_amounts.total_amount AS total_amount
FROM invoices
LEFT JOIN (
SELECT invoices.id AS invoice_id,
COALESCE(SUM(invoice_payments.amount), 0) AS amount_paid
FROM invoices
LEFT JOIN invoice_payments
ON invoices.id = invoice_payments.invoice_id
GROUP BY invoices.id
) AS invoice_payment_amounts
ON invoices.id = invoice_payment_amounts.invoice_id
LEFT JOIN (
SELECT invoices.id AS invoice_id,
COALESCE(SUM(invoice_items.item_price), 0) AS total_amount
FROM invoices
LEFT JOIN invoice_items
ON invoices.id = invoice_items.invoice_id
GROUP BY invoices.id
) AS invoice_item_amounts
ON invoices.id = invoice_item_amounts.invoice_id
WHERE amount_paid < total_amount

但是......现在我需要把它放到 rails 中(可能作为一个范围)。我可以使用 find_by_sql,但它会返回一个数组,而不是一个 ActiveRecord::Relation,这不是我需要的,因为我想将它与其他范围链接(例如,有一个过期范围,它使用这个), 等等。

所以原始 SQL 可能不是去这里的正确方法......但什么是?我无法在 activerecord 的查询语言中执行此操作。

到目前为止我得到的最接近的是这个:
Invoice.select('invoices.*, SUM(invoice_items.price) AS total, SUM(invoice_payments.amount) AS amount_paid').
joins(:invoice_payments, :invoice_items).
group('invoices.id').
where('amount_paid < total')

但这失败了,因为在像 #1 这样的订单上,多次付款,它错误地将订单价格加倍(由于多次连接),显示它仍未付款。我在 SQL 中遇到了同样的问题,这就是为什么我按照我的方式构建它。

这里有什么想法吗?

最佳答案

您可以使用 group by 获取结果和 having MySQL的子句为:

纯 MySQL 查询:

  SELECT `invoices`.* FROM `invoices` 
INNER JOIN `invoice_items` ON
`invoice_items`.`invoice_id` = `invoices`.`id`
INNER JOIN `invoice_payments` ON
`invoice_payments`.`invoice_id` = `invoices`.`id`
GROUP BY invoices.id
HAVING sum(invoice_items.price) < sum(invoice_payments.amount)

ActiveRecord 查询:
Invoice.joins(:invoice_items, :invoice_payments).group("invoices.id").having("sum(invoice_items.price) < sum(:invoice_payments.amount)")

关于sql - 多表发票SUM比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46919883/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com