2013-10-02 231 views
0

请帮我解释为什么添加GROUP BY子句会更改查询的结果。所有其他条件保持不变,删除GROUP BY子句将产生与添加GROUP BY子句不同的结果。MySQL - GROUP BY更改结果

在我看来,GROUP BY只会将结果按字段分组,而不会改变计数。

我需要通过table2.name来组织数据,并且得到的计数为每个

SELECT table2.name, COUNT(DISTINCT(op.id)) 
FROM op INNER JOIN table1 ON table1.EID = op.ID 
    INNER JOIN table3 ON table3.id = table1.jobid 
    INNER JOIN table2 ON table2.id = table3.CatID 
WHERE op.ActiveStartDate <= NOW() 
    AND op.ActiveEndDate >= NOW() 
GROUP BY table2.name 
ORDER BY COUNT(*) DESC; 
+0

我们无法预测您看到了什么,请分享这两个查询结果 – Kuzgun

+0

奇怪是查询可以在没有GROUP BY的情况下工作(因为MySql对所有未包含在GROUP BY子句中的标量字段应用隐式LIMIT 1) –

+1

所有聚合函数(如'count')根据组的记录计算(如果已定义)。否则,他们将根据完整的结果集进行计算。 –

回答

0

COUNT是一个聚集函数,其中,像其它集合函数这样MINMAXSUM等加到到组中的每个元素。

MySql比其他数据库更灵活一点,因为它允许您在不使用GROUP BY的情况下使用COUNT(*):这是不允许的。 SQL Server或Oracle。

+0

然后写一个更好的方法是什么? – Ken

+0

我个人会这样写,因为它更具说明性,并与其他SQL方言一致。 – davek

+0

对不起,怎么办?我拥有它的方式会产生错误的结果。如果我使用COUNT(*),结果也是错误的。如果我在没有GROUP BY的情况下使用COUNT(*),结果也是错误的。 – Ken

0

这是因为所有GROUP BY操作都在任何ORDER BY操作之前应用。但是在上面的例子中,ORDER子句中有一个分组函数。这意味着,实际上是ORDER BY所得到的数据组的前被施加3个分组:

  • COUNT(DISTINCT(op.id))
  • GROUP BY table2.name
  • COUNT(*)

令人遗憾的是,我不太了解MySQL的内部工作原理,知道为什么这会产生确切的效果,但我知道如何解决这个问题。

的解决方案是一个子选择即

SELECT * 
FROM (
    SELECT 
     table2.name, 
     COUNT(DISTINCT(op.id)), 
     COUNT(*) as c 
    FROM op 
     JOIN table1 ON table1.EID = op.ID 
     JOIN table3 ON table3.id = table1.jobid 
     JOIN table2 ON table2.id = table3.CatID 
    WHERE 
     op.ActiveStartDate <= NOW() 
     AND op.ActiveEndDate >= NOW() 
    GROUP BY 
     table2.name 
) AS t 
ORDER BY 
    t.c DESC 

希望这不会让查询太慢了!