分组并难以理解

时间:2019-01-06 06:50:50

标签: sql ms-access select group-by

我正在查看我在Access数据库中没有进行的一些SQL查询。

其中一个SQL查询的内容如下:

select column1 from table1 group by column1 having count(*)>1

此查询的目的是在column1中查找多次出现的值。我可以验证此查询是否正常工作,并返回出现多次的列值。

但是我不明白为什么这个查询有效。据我了解,使用group by将删除重复的字段。例如,如果column1有

    column1
    apple
    mango
    mango

执行group by (column1)

    column1
    apple
    mango

在这一点上,如果我们执行having count(*)>1having count(column1)>1,它应该不返回任何结果,因为group by已经删除了重复字段。但是显然,我错了,因为上面的SQL语句确实给出了准确的结果。

请问,让我了解我的问题吗?

编辑1:

除了可以接受的答案之外,我的this文章还介绍了SQL操作的顺序,确实帮助了我理解

3 个答案:

答案 0 :(得分:2)

group by不仅会删除重复的值-它还会对group by子句的每个不同值返回一行,并允许您针对此类唯一值应用聚合函数。

在此查询中,您实际上查询column1的值和count(*)的结果每个column1的值,然后使用having子句仅返回column1大于1的count(*)的值。

答案 1 :(得分:2)

您误解了HAVING的工作方式。实际上,您可以使用子查询来考虑它。您的查询等同于:

select column1
from (select column1, count(*) as cnt
      from table1
      group by column1
     ) as t
having cnt > 1;

也就是说,having在发生聚合之后 过滤聚合查询。但是,聚合功能是按每个组应用的。因此count(*)正在计算每个组中的行数。这就是为什么它标识重复项。

答案 2 :(得分:1)

GROUP BY子句根据您提到的字段对选择进行分组,在这种情况下为column1,但可以是组合的列(例如column1,column2)。 顺便说一句,我认为如果您运行:

SELECT column1, Count(*) AS [Count], MIN(column2) AS MinColumn2, MAX(column2) AS MaxColumn2
FROM table1 
GROUP BY column1;

将帮助您了解分组的工作原理。直接按任何列过滤时,可以使用WHERE条件,但如果要对从分组中计算出的任何字段进行过滤,则需要使用HAVING子句。