选择两个不同表的SUM

时间:2014-08-14 13:30:20

标签: mysql sql

我有一个订单表,其中包含以下内容:

id
order_total
delivery_cost
customer_id

我还有一个交易表,其中包含:

id
amount
customer_id
status

我想做的是,

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

然后

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

然后使用数据减去订单总数中的总金额。

我尝试过使用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
) 

但这根本不起作用。任何帮助将不胜感激。

7 个答案:

答案 0 :(得分:2)

这两个数据集是有效自治的,但假设没有订单的客户不太可能有交易,你可以用LEFT JOIN而不是一个完全的外连接来实现你的结果 - 但如果你只是加入基表那么你' ll可能会从中间结果集中重复的一个表中获取值(这就是为什么当客户在每个表中只有一行时,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

(此处'GROUP BY'和'ON'条款是多余的,因为您只查看单个客户 - 但多个客户需要这些条款。)

请注意,根据交易总和计算余额在技术上是正确的,但不能很好地扩展 - 对于大型系统而言,更好的解决方案(尽管它违反了规范化规则)是维护统一的交易表和余额对于帐户以及每笔交易金额 - 或者使用检查点。

答案 1 :(得分:0)

您只需在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;

答案 2 :(得分:0)

使用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';

答案 3 :(得分:0)

这可以为您提供每位客户的帐户余额吗?

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

答案 4 :(得分:0)

您可以加入查询结果并执行计算,将不带分组的总和作为一行记录,因此外部查询中的总和并不意味着当您只有一行时并根据您的计算逻辑联合与它无关

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)

答案 5 :(得分:0)

由于您只关心单个客户,只需将它们列为两个不同的查询作为源...

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

现在,如果您希望所有客户都看到谁是优秀的,请将客户的ID添加到每个查询并应用组,但随后更改为LEFT-JOIN,以便您获得所有订单或< / p>

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

答案 6 :(得分:0)

我认为如果你尝试内联视图,这种方法效果最好。在下面的代码块中,检查Group By子句,您可能需要在Group By中添加更多字段,具体取决于您在Inner 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;