问题描述
我知道在分组/聚合等方面存在很多混乱,我认为我对整个事情都相当了解,直到我看到类似的东西
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
的值。