具有3个关联表的MySQL SUM

时间:2019-06-28 16:15:56

标签: mysql

我有3个带有以下各列的表,它们是:

  1. THead-HeadID(PK),填充码,OKqty,TotNGqty
  2. TDetail-HeadID(FK),进程,名称,子代码
  3. TSubDetail-子代码(FK),NGcode,NGqty

3个表的关系如下:THead-TDetail-TSubDetail。

我希望下面的图像可以清楚地显示它们。

Tables with sample data

这是我的MySQL查询:

SELECT
THead.padcode,
SUM(THead.okqty) AS OK,
SUM(THead.TotNGqty) AS TOTALNG,
SUM(If(TSubDetail.NGCode = 'L3', NGqty, 0)) AS L3

FROM(THead JOIN TDetail ON THead.HeadID = TDetail.HeadID)
                        JOIN TSubDetail ON TDetail.Subcode=TSubDetail.Subcode

GROUP BY padcode

我想对OK Qty和TotNGqty求和,而不添加来自同一TSubDetail.Subcode的相同值。我已经尝试过DISTINCT,但这不是解决方案。

从图像中您可以从黄色突出显示的示例中看到:

对于Padcode ='KVBS-B'

  

我想从表头中获取OK数量= 2845,并且总和NG = 705。

     

但是从上面的查询中,我得到了错误的结果,OK = 3245,NG =   905。

我知道来自同一TSubDetail.Subcode的相同值被多次添加。但是正确的查询是什么,这样我才能得到真实的结果?

我希望有人能帮助我并解释什么是正确的查询。预先感谢您的帮助。

4 个答案:

答案 0 :(得分:0)

如果选择此选项,则可以看到哪些行是双行,因此将被计为双行:

SELECT
  THead.padcode,
  THead.okqty,
  THead.TotNGqty
  TDetail.HeadID,
  TsubDetail.Subcode,
  If(TSubDetail.NGCode = 'L3', NGqty, 0) AS L3
FROM THead 
  JOIN TDetail ON THead.HeadID = TDetail.HeadID
  JOIN TSubDetail ON TDetail.Subcode=TSubDetail.Subcode

答案 1 :(得分:0)

您正在显示数据的子集,因此很难确定答案,但是您的GROUP BY子句仅包含“ padcode”列,而不包含HeadID列。

我认为在整个表中,您不仅具有黄色显示的记录,而且具有多个HeadID的相同填充码(KVBS-B)的记录。结果,它们也被求和,但是由于GROUP BY太笼统,您看不到哪个。

答案 2 :(得分:0)

鉴于上面的查询是必需的,因此没有任何其他约束。 您可以通过运行两个查询来做到这一点。

对于第一个查询,可以通过对填充码分组而不加入其他表来获得OK和TOTALNG之和。对于第二个查询,通过联接表并最终通过填充码将上述两个查询联接起来,得出总和L3。

答案 3 :(得分:0)

在SELECT子句中使用相关的子查询。这样okqtyTotNGqty不会乘以TSubDetail中相关行的数量。

SELECT
    THead.padcode,
    SUM(THead.okqty) AS OK,
    SUM(THead.TotNGqty) AS TOTALNG,
    SUM((
        SELECT SUM(TSubDetail.NGqty)
        FROM TDetail
        JOIN TSubDetail ON TDetail.Subcode=TSubDetail.Subcode
        WHERE THead.HeadID = TDetail.HeadID
          AND TSubDetail.NGCode = 'L3'
    )) AS L3 
FROM THead
GROUP BY padcode

或聚合两次。首先在派生表中获得SUM(TSubDetail.NGqty)。然后在外部查询中与THead联接:

SELECT
    THead.padcode,
    SUM(THead.okqty) AS OK,
    SUM(THead.TotNGqty) AS TOTALNG,
    SUM(x.L3) as L3
FROM THead
LEFT JOIN(
    SELECT TDetail.HeadID, SUM(TSubDetail.NGqty) as L3
    FROM TDetail
    JOIN TSubDetail ON TDetail.Subcode=TSubDetail.Subcode
    WHERE TSubDetail.NGCode = 'L3'
    GROUP BY TDetail.HeadID
) x ON x.HeadID = THead.HeadID
GROUP BY THead.padcode