在MySQL中使用sql_mode = only_full_group_by进行错误分组

时间:2019-04-07 14:25:31

标签: mysql sql

尝试以下查询,但是我得到了;错误代码:1055。SELECT列表的表达式#3不在GROUP BY子句中,并且包含未聚合的列'PDC.PLG.LogDateTime',该列在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by

不兼容

我知道这是因为只有完整的分组方式;如何重构这种查询?

SELECT     
SUM(PLG.Qty) AS TotQty,
SUM(PLG.ScrapQty) AS ScrpQty,   
(
SELECT SUM(PLL.Qty) 
FROM ProductionLog AS PLL
INNER JOIN ProductionPlan PPP ON PPP.PlanId = PLL.PlanId
WHERE 
DATE(LogDateTime) = DATE(PLG.LogDateTime) AND 
LogType = 8 AND 
PPP.StationId = PP.StationId

) AS RwrkQty,

DATE(PLG.LogDateTime) AS LogDate,
S.StationName
FROM ProductionLog AS PLG
INNER JOIN ProductionPlan  AS PP ON PLG.PlanId = PP.PlanId
INNER JOIN Station AS S ON S.StationId = PP.StationId
WHERE PLG.Logtype IN (4)

GROUP BY S.StationId,DATE(PLG.LogDateTime)

1 个答案:

答案 0 :(得分:1)

首先,使用GROUP BY进行适当的查询意味着无论您要返回什么结果字段,GROUP BY都应包括未应用任何汇总(最小,最大,总和,平均等)的所有字段。缺少的是列表中有一个未聚合的额外列,但该列也不属于group by。因此,要么将此非聚合字段添加到分组依据(即使分组依据中的最后一个字段),要么对其应用一些聚合。

现在,清除原始查询的可读性,以了解下一个查询的位置和/或子查询的可读性。

SELECT     
      SUM(PLG.Qty) AS TotQty,
      SUM(PLG.ScrapQty) AS ScrpQty,   
      ( SELECT SUM(PLL.Qty)
           FROM ProductionLog AS PLL
              INNER JOIN ProductionPlan PPP 
                 ON PPP.PlanId = PLL.PlanId
           WHERE 
                  DATE(LogDateTime) = DATE(PLG.LogDateTime) 
              AND LogType = 8 
              AND PPP.StationId = PP.StationId ) AS RwrkQty,
      DATE(PLG.LogDateTime) AS LogDate,
      S.StationName
   FROM 
      ProductionLog AS PLG
         INNER JOIN ProductionPlan  AS PP 
            ON PLG.PlanId = PP.PlanId
         INNER JOIN Station AS S 
            ON S.StationId = PP.StationId
   WHERE 
      PLG.Logtype IN (4)
   GROUP BY 
      S.StationId,
      DATE(PLG.LogDateTime)

在您的方案中,基于查询的第3列已在INSIDE内聚合,但对于OUTER查询,则未聚合。为了简化此过程,只需将IT包装在

之类的MIN()中
      MIN( ( SELECT SUM(PLL.Qty)
           FROM ProductionLog AS PLL
              INNER JOIN ProductionPlan PPP 
                 ON PPP.PlanId = PLL.PlanId
           WHERE 
                  DATE(LogDateTime) = DATE(PLG.LogDateTime) 
              AND LogType = 8 
              AND PPP.StationId = PP.StationId ) ) AS RwrkQty,

由于内部查询仅返回1行,因此总和1行将始终返回相同的值。