多重连接中的MySQL SUM函数

4

你好,这是我的情况,我有这些表格:

Customer {id,name}
Charges {id,amount,customer_id}
Taxes {id,amount,charge_id}

我想对费用和税收金额进行求和,然后按客户ID分组,以下是我的查询语句:

SELECT SUM(ch.amount),SUM(t.amount)
FROM Customer c
LEFT JOIN Charges ch ON ch.customer_id = c.id
LEFT JOIN Taxes t ON t.charge_id = ch.id
GROUP BY c.id;

如果我有一个顾客收费,但对应该次收费有两种税收,那么在使用SUM函数时,它将会把这个收费金额计算两次。例如,如果要显示10美元,它实际上会显示20美元。
我知道可以通过子查询来解决这个问题,但我想知道是否有其他方法可以在不用子查询的情况下得到正确的值,比如修改我上面使用的查询。
谢谢!
更新后的回答(无需使用子查询):
SELECT
  SUM(CASE WHEN @ch_id != ch.id
    THEN ch.amount END) AS ch_amount,
  SUM(t.amount)         AS t_sum,
  c.*,
  @ch_id := ch.id
FROM
  Customer c
  LEFT JOIN charges ch ON c.id = ch.reservation_id
  LEFT JOIN taxes t ON ch.id = t.charge_id
GROUP BY rs.id;
2个回答

6

您想知道是否可以在没有子查询的情况下完成此操作。不行。

如果Charges中的一行有多个对应的Taxes行,则无法简单地将这些表连接而不重复Charges行。然后,就像您发现的那样,当您将它们加起来时,您会得到多个副本。

您需要一种方法来获取每个Charge的一个虚拟表(子查询)。

                    SELECT ch.customer_id,
                           ch.amount amount,
                           tx.tax tax
                      FROM Charges
                      LEFT JOIN (  
                                  SELECT SUM(amount) tax,
                                         charge_id 
                                    FROM Taxes
                                   GROUP BY charge_id
                          ) tx ON ch.id = tx.charge_id

您可以将该子查询连接到您的客户表中,以按客户汇总销售数据。

1
这很麻烦,因为有多个层次结构。我建议:
SELECT c.id, ch.charge_amount, ch.taxes_amount
FROM Customer c LEFT JOIN
     (SELECT ch.customer_id, SUM(ch.amount) as charge_amount,
             SUM(t.taxes_amount) as taxes_amount
      FROM Charges ch LEFT JOIN
           (SELECT t.charge_id, SUM(t.amounts) as taxes_amount
            FROM taxes t
            GROUP BY t.charge_id
           ) t
           ON t.charge_id = ch.id
      GROUP BY ch.customer_id
     ) ch
     ON ch.customer_id = c.id;

如果一个客户有多个收费或一个收费有多种税,则您将无法在没有某种形式的子查询的情况下解决此问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接