【问题标题】:SQL Aggregate with join giving incorrect results带有连接的 SQL 聚合给出不正确的结果
【发布时间】:2017-10-29 13:55:10
【问题描述】:

为了学习 SQL,我在 Excel 中生成的几个表中添加了一些虚拟数据。我有一张用于客户、订单标题和订单行的表格。

我正在尝试检查客户余额、订单标题总计和行总计是否全部匹配。

但是当我运行这个查询时,我得到了 orderheader 的错误输出,我相信这是因为它对 orderlines 表被引用的次数进行了 SUM。

谁能告诉我正确的做法?

SELECT 
    cus.cus_id,
    cus.cus_name,
    cus.cus_balance,
    SUM(orderheader.orderheader_currentsell) AS orderHeader_total,
    SUM(orderlines.orderlines_currentsell) AS orderLines_total
FROM
    cus
        JOIN
    orderheader ON orderheader.orderHeader_customer = cus.cus_id
        JOIN
    orderlines ON orderlines.orderlines_orderid = orderheader.orderHeader_id
GROUP BY cus.cus_name

输出(突出显示的列应与其他值相同。)

【问题讨论】:

    标签: mysql sql join sum aggregate


    【解决方案1】:

    标题有多行。要解决此问题,请在执行join 之前聚合。在您的情况下,仅汇总订单行就足够了:

    SELECT c.cus_id, c.cus_name, c.cus_balance,
        SUM(oh.orderheader_currentsell) AS orderHeader_total,
        SUM(ol.orderLines_total) AS orderLines_total
    FROM cus c JOIN
         orderheader oh
         ON oh.orderHeader_customer = c.cus_id JOIN
         (SELECT ol.orderlines_orderid, SUM((ol.orderlines_currentsell) as orderLines_total
          FROM orderlines ol
          GROUP BY ol.orderlines_orderid
         ) ol
         ON ol.orderlines_orderid = oh.orderHeader_id
    GROUP BY cus.cus_name;
    

    【讨论】:

    • 它的工作原理让我有点困惑(顺便说一句,它工作得很好)。您能解释一下联接中的 select 语句在做什么吗?由于某种原因,我无法理解它。
    • @LewisMorris 。 . .这称为子查询或派生表:dev.mysql.com/doc/refman/5.7/en/derived-tables.html
    【解决方案2】:

    因为你有不同级别的分组,这不是微不足道的,你需要子选择。

    您可以将每位客户的总数计算为字段列表中的子选择。在下面的代码中,我仅针对订单执行此操作,但您可以对仍由分组解决的订单行执行相同操作。

    SELECT 
        cus.cus_id,
        cus.cus_name,
        cus.cus_balance,
        ( SELECT 
              SUM(orderheader_currentsell) 
          FROM
              orderheader 
          WHERE 
              orderheader.orderHeader_customer = cus.cus_id) AS orderHeader_total,
        SUM(orderlines.orderlines_currentsell) AS orderLines_total
    FROM
        cus
    JOIN
        orderlines ON orderlines.orderlines_orderid = orderheader.orderHeader_id
    GROUP BY cus.cus_name
    

    【讨论】:

      【解决方案3】:

      这是乍一看,但我注意到你有:

      cus.cus_id,
      cus.cus_name,
      cus.cus_balance,
      

      作为非聚合列。但是在您的 Group-By 中,您只有:

      GROUP BY cus.cus_name 
      

      Group By 应包括所有非聚合列。这可能是您没有得到预期结果的原因。那将改为:

      GROUP BY cus.cus_id,
               cus.cus_name,
               cus.cus_balance
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-07
        相关资源
        最近更新 更多