汇总在也要分组的列上

问题描述

我知道在分组/聚合等方面存在很多混乱,我认为我对整个事情都相当了解,直到我看到类似的东西

SELECT A,SUM(B)
FROM T
GROUP BY A
HAVING COUNT(A)>1;

起初,这使我感到困惑,因为它似乎在对也要分组的列上执行聚合是多余的,因为根据定义,该组的值将是不同的。但是后来我考虑了一下,如果聚合是在分组之前完成的,那么对于表中的重复值就有意义了。在我看来,它似乎更像是这种查询

SELECT A,SUM(B)
FROM T
WHERE A in (SELECT A FROM T GROUP BY A HAVING COUNT(*)>1)
GROUP BY A;

完成分组后,与每个组上的另一个选择运算符不同(因为对我来说这没有多大意义)。

所以我的问题是多方面的:被分组的元素是否可以完全包含在HAVING子句中?可以对分组的元素进行汇总(在HAVING子句或其他类似SELECT子句中)吗?如果前面的陈述成立,那么我对该操作含义的理解正确吗?

注意:这个问题主要是关于标准(ansi)sql的,但是有关特定实现的信息也很有趣

解决方法

聚合函数的参数可以包括要聚合的键。

也就是说,在每个组中计算的更常见方法是使用COUNT(*)。我建议:

SELECT A,SUM(B)
FROM T
GROUP BY A
HAVING COUNT(*) > 1;

使用COUNT(A)会产生一些开销,因为需要针对每一行中的A来检查NULL的值。