简体   繁体   English

选择两个不同表的总和

[英]Select the SUM of two different tables

I have an orders table which consists of the following: 我有一个包含以下内容的订单表:

id
order_total
delivery_cost
customer_id

I also have a transactions table which has: 我也有一个交易表,其中有:

id
amount
customer_id
status

What I'm trying to do is, 我想做的是

SELECT SUM(order_total + delivery_cost) FROM orders WHERE customer_id = '1'

then 然后

SELECT SUM(amount) FROM transactions WHERE customer_id = '1' AND transaction_status = 'Paid'

Then with the data, minus the total amount from the order totals. 然后使用数据从订单总计中减去总金额。

I've tried different queries using JOINS, but I just can't get my head around it, for example: 我已经尝试过使用JOINS进行不同的查询,但是我无法理解,例如:

SELECT SUM(OrdersTotal - TransactionTotal) as AccountBalance

FROM (
SELECT SUM(`order_total` + `delivery_cost`) FROM `orders` as OrdersTotal 
UNION ALL 
SELECT SUM(`amount`) FROM `transactions` WHERE `transaction_status` = 'Paid' as TransactionTotal
) 

but this didn't work at all. 但这根本没有用。 Any help would be greatly appreciated. 任何帮助将不胜感激。

The two datasets are effectively autonomous but assuming that it's unlikely to have transactions for a customer without orders, you can acheive your result with a LEFT JOIN rather than a ful outer join - but if you simply join the base tables then you'll likely get values from one table repeated in the interim result set (this is why Joseph B's answer is wrong when a customer has something other than a single row in each table). 这两个数据集是有效自治的,但是假设没有订单的客户不太可能进行交易,则可以使用LEFT JOIN而不是有效的外部联接来实现结果-但是,如果仅联接基本表,则可能会得到临时结果集中重复的一张表中的值(这就是为什么当客户在每张表中除一行以外的其他地方,Joseph B的答案都是错误的)。

SELECT ordered_value-IFNULL(paid_value,0) AS acct_balance
FROM
(
  SELECT customer_id, SUM(order_total + delivery_cost) AS ordered_value
  FROM orders 
  WHERE customer_id = '1'
  GROUP BY customer_id
) AS orders
LEFT JOIN 
(
  SELECT customer_id, SUM(amount) AS paid_value
  FROM transactions 
  WHERE customer_id = '1' 
  AND transaction_status = 'Paid'
  FROUP BY customer_id
) as payments
ON orders.customer_id = payments.customer_id

(here the 'GROUP BY' and 'ON' clauses are redundant since your only looking at a single customer - but are required for multiple customers). (这里的“ GROUP BY”和“ ON”子句是多余的,因为您仅查看单个客户-但多个客户都需要)。

Note that calculating a balance based on a sum of transactions is technically correct, it does not scale well - for large systems a better solution (although it breaks the rules of normalization) is to maintain a unified table of transactions and a balance for for the account along with each transaction amount - alternatively use checkpointing. 请注意,基于交易总和计算余额在技术上是正确的,不能很好地扩展-对于大型系统,更好的解决方案(尽管它破坏了规范化规则)是维护统一的交易表,而对于帐户以及每个交易金额-或者使用检查点。

You can just name the column in your union all query and sum on that: 您可以在union all查询中将列命名为该列并求和:

SELECT SUM(col) as AccountBalance
FROM (SELECT SUM(`order_total` + `delivery_cost`) as col FROM `orders` as OrdersTotal 
      UNION ALL 
      SELECT SUM(`amount`) FROM `transactions` WHERE `transaction_status` = 'Paid' as    TransactionTotal
     ) t;

Try this query using a JOIN: 使用JOIN尝试以下查询:

SELECT
    SUM(o.order_total + o.delivery_cost) - SUM(t.amount) AS AccountBalance
FROM orders o
INNER JOIN transactions t
ON o.customer_id = t.customer_id AND o.customer_id = '1' AND t.transaction_status = 'Paid';

This should give you the account balance for each customer? 这应该给您每个客户的帐户余额吗?

SELECT 
    ISNULL(o.customer_id, t.customer_id) AS customer_id
    OrdersTotal - TransactionTotal AS AccountBalance
FROM (
    SELECT 
        customer_id, 
        SUM(order_total + delivery_cost) AS OrdersTotal 
    FROM 
        orders 
    GROUP BY 
        customer_id) o
FULL OUTER JOIN (
    SELECT 
        customer_id, 
        SUM(amount) AS TransactionTotal 
    FROM 
        transactions 
    WHERE 
        transaction_status = 'Paid' 
    GROUP BY 
        customer_id) t
ON t.customer_id = o.customer_id

You can join the results of your queries and perform your calculations ,note sum without group by will result as one row so the sum in outer query doesn't mean when you have only one row and according to your logic of calculation union has nothing to do with it 您可以合并查询的结果并执行计算,请注意不带分组依据的总和将作为一行,因此外部查询中的总和并不意味着当您只有一行并且根据您的计算逻辑并没有任何关系时用它做

SELECT t1.OrdersTotal - t2 .TransactionTotal AS AccountBalance
FROM (
SELECT SUM(order_total + delivery_cost) OrdersTotal ,customer_id 
 FROM orders 
 WHERE customer_id = '1'
) t1
JOIN (
SELECT SUM(amount) TransactionTotal ,customer_id
FROM transactions 
WHERE customer_id = '1' AND transaction_status = 'Paid'
) t2 USING(customer_id)

Since you are only concerned about a single customer, just have them listed as two different queries as the source... 由于您只关注一个客户,因此只需将他们列为两个不同的查询作为来源即可...

select
      charges.chg - paid.pay as Balance
   from
      ( SELECT SUM(order_total + delivery_cost) chg
           FROM orders 
           WHERE customer_id = '1' ) charges,
      ( SELECT SUM(amount)  pay
           FROM transactions 
           WHERE customer_id = '1' AND transaction_status = 'Paid' ) paid

Now, if you wanted for all customers to see who is outstanding, add the customer's ID to each query and apply a group by, but then change to a LEFT-JOIN so you get all orders with or 现在,如果您想让所有客户看到谁是杰出的客户,则将客户的ID添加到每个查询并应用分组依据,然后更改为LEFT-JOIN,以便使用或获得所有订单

select
      charges.customer_id,
      charges.chg - coalesce( paid.pay, 0 ) as Balance
   from
      ( SELECT customer_id, SUM(order_total + delivery_cost) chg
           FROM orders 
           group by customer_id ) charges
         LEFT JOIN ( SELECT customer_id, SUM(amount)  pay
                        FROM transactions 
                        where transaction_status = 'Paid' 
                        group by customer_id ) paid
          on charges.customer_id = paid.customer_id

I think this works best if you try an inline view. 我认为,如果您尝试内联视图,则效果最佳。 In the code block below, check the Group By clause, you might need to add more fields in the Group By depending on what you're selecting in the Inner SELECT statements.Try the code below: 在下面的代码块中,选中Group By子句,您可能需要在Group By中添加更多字段,具体取决于您在内部SELECT语句中选择的内容。尝试以下代码:

SELECT
  SUM(Totals.OrdersTotal-Totals.TransactionTotal)
  FROM 
      (SELECT
           SUM(ord.order_total + ord.delivery_cost) AS OrdersTotal
           , SUM(trans.amount) AS TransactionTotal
           FROM orders ord
                INNER JOIN transactions trans
                     ON ord.customer_id = trans.customer_id
           WHERE
                ord.customer_id =1
                AND trans.transaction_status = 'Paid'
           GROUP BY
                ord.customer_id
      ) Totals;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM