【问题标题】:Inner Join for 3 tables with SUM of two columns in SQL Query?SQL查询中两列总和的3个表的内连接?
【发布时间】:2020-07-15 22:33:18
【问题描述】:

我有以下三个表:

我有以下查询要加入以上 3 个表

     customer.customer_id,
     customer.name,
     SUM(sales.total),
     sales.created_at,
     SUM(sales_payments.amount)
FROM
     sales INNER JOIN customer ON customer.customer_id = sales.customer_id
     INNER JOIN sales_payments ON sales.customer_id = sales_payments.customer_id
WHERE sales.created_at ='2020-04-03'
GROUP By customer.name 

上述查询的结果如下所示

sales.total 的总和是 sales.total 列的实际总和的两倍,它有 2 行计数,我需要该列的实际总和,而不是那些行的总和加倍,谢谢你提前帮忙..

【问题讨论】:

    标签: mysql sql sql-server join


    【解决方案1】:

    问题

    这里的问题是存在连续的内连接,并且在第二个内连接中获取的行数不受限制。因此,由于我们没有在 sales 和 sales_payment 表之间的连接中添加 sales_payment_id 条件,因此 sales 表中的一行(在本例中为 customer_id 2)将映射到 payment 表中的 2 行。这会导致重新考虑相同的值。 也就是说,customer_id 2 在 3 个表之间的映射是 1:1:2 而不是 1:1:1。

    解决方案

    解决方案 1:正如 Gordon 所说,您可以先聚合 sales_payments 表的金额值,然后聚合 sales 表中的值。

    解决方案 2:或者(恕我直言,一种更好的方法),您可以在 sales 和 sales_payment 表之间添加外键。例如,sales_payment 表的sales_payment_id 列也可以引入sales 表中。这将促进这些表之间的连接,并减少查询数据时的额外开销。

    查询将如下所示:

    `SELECT c.customer_id,
      c.name,
      SUM(s.total),
      s.created_at,
      SUM(sp.amount)
    FROM customer c
    INNER JOIN sales s
    ON c.customer_id = s.customer_id
    INNER JOIN sales_payments sp
    ON c.customer_id        = sp.customer_id
    AND s.sales_payments_id = sp.sales_payments_id
    WHERE s.created_at      ='2020-04-03'
    GROUP BY c.customer_id,
    c.name,
    s.created_at ;`
    

    希望有帮助!

    【讨论】:

    • Gordon Linof 的回答对我有用,当我执行您的查询时,我收到以下错误“Unknown Column 's.sales_payment_id' 无论如何感谢您的努力和帮助”
    • 是的,这就是我的建议是“sales_payment 表的 sales_payment_id 也可以在 sales 表中引入”的原因。为此,我们需要在 sales 表中添加 sales_payment_id 列。但是很酷,很高兴问题得到解决。 :)
    • 嗨 Mohamed,由于声誉限制,我无法对 Gordon 的回答添加评论。但我认为,如果您在最终选择中从 SUM(sp.amount) 中删除 SUM 函数调用,它应该在那里工作,即SELECT c.customer_id, c.name, SUM(s.total), s.created_at, sp.amount FROM customer c JOIN .... 并且您还需要在 GROUP BY 中添加 sp.amount结尾。我们这样做是因为我们已经在下面的联接中聚合了 sales_payment_amount。希望这有用!
    【解决方案2】:

    每个客户有多个 sales_paymentssales 行。您需要预先聚合以获得正确的值:

    SELECT c.customer_id, c.name, s.created_at, s.total, sp.amount
    FROM customer c JOIN
         (SELECT s.customer_id, s.created_at, SUM(s.total) as total
          FROM sales s
          WHERE s.created_at ='2020-04-03'
          GROUP BY s.customer_id, s.created_at
         ) s
         ON c.customer_id = s.customer_id JOIN
         (SELECT sp.customer_id, SUM(sp.amount) as amount
          FROM sales_payments sp
          GROUP BY sp.customer_id
         ) sp
         ON s.customer_id = sp.customer_id
    

    【讨论】:

    • 您的回答对s.total 有效,但现在'sp.amount' 翻了一番,有什么解决方案可以克服这个问题
    • @MohamedFarookMohamedFazrin 。 . .然后你需要在JOINing之前把它们都聚合起来,不需要外层聚合。
    • @MohamedFarookMohamedFazrin 。 . .修改后的版本不行吗?
    猜你喜欢
    • 1970-01-01
    • 2015-06-09
    • 2015-12-11
    • 2018-05-09
    • 2015-11-02
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 2020-11-10
    相关资源
    最近更新 更多