【问题标题】:how does the groupby and count work in sqlgroupby 和 count 在 sql 中是如何工作的
【发布时间】:2011-05-01 15:38:17
【问题描述】:

1> select browser,count(*) from logtest group by browser;

+-----------+----------+
| browser   | count(*) |
+-----------+----------+
| Firefox 3 |       14 |
| Unknown   |       11 |
+-----------+----------+

集合中有 2 行

2>select browser,count(browser) from logtest group by browser;

+-----------+----------------+
| browser   | count(browser) |
+-----------+----------------+
| Firefox 3 |             14 |
| Unknown   |             11 |
+-----------+----------------+

集合中有 2 行

3>select browser,count(browser) from logtest;

+-----------+----------------+
| browser   | count(browser) |
+-----------+----------------+
| Firefox 3 |             25 |
+-----------+----------------+

集合中的 1 行

为什么查询方式1>和2>的结果是一样的? count(*) 和 count(somefiled) 没有区别吗?

另外,为什么查询 2> 和 3> 会导致不同的结果,为什么 groupby 如此神奇?它是如何工作的?


更新: 我正在使用 MySQL5.1。 :)

【问题讨论】:

    标签: sql mysql count group-by


    【解决方案1】:

    选择相关地为您提供结果集。如果您按字段对选择进行分组,则结果集的行将按该字段分组,并且结果集中的每一行将特定于结果组。

    例如,您有一个名为 Animals 的表,其中包含以下字段:

    Type | Gender | Name
    

    如果您正在运行此查询(例如在 MySQL 中):

     select Type, Gender, Name from Animals where Type <> 'Pig'
    

    你会得到所有不是“猪”的动物。如果一行的 Type = 'pig',它将被包含在结果中。

    这个查询:

    select Type, Gender, count(*) from Animals group by Type, Gender
    

    会有这么多行:类型数 * 性别数

    您可以使用 MySQL 中的having子句为您的组创建条件。

    阅读更多here

    count(*)和count(browser)的区别在于第一个会返回所有记录的个数,第二个会返回not (browser is null)所在的所有记录个数。

    尝试在browser is null 处插入一行,然后运行 ​​1) 和 2),这是最好的测试。

    【讨论】:

    • 我测试了你说的,你是对的:)。对于第三个查询,很多人说可能其他db不支持,是不是说,当使用select field时,cound(somefiled);,group by必须附加?
    • 视情况而定。如果要计算所有记录,则不需要分组。如果要统计 select 的组的记录,则 group by 需要。真的只取决于你的愿望。
    【解决方案2】:

    您必须指定您正在使用的 SQL 实现或产品才能获得准确的答案。这是 MySQL 吗?

    也就是说:

    查询 1 和 2几乎相同。 COUNT(*) 将为组中的每一行添加一个计数。每次 FieldName 中的值不为 NULL 时,COUNT(FieldName) 将加 1。在您的示例中,Browser 永远不会为 NULL,因此结果是相同的。

    什么时候会有所不同?如果您的表在浏览器字段中包含 10 行 NULL,则第一个查询将有一个附加行 (NULL) | 10 和第二个查询将报告 (NULL) | 0.

    第三个查询不会在某些 SQL 实现中运行。因为您实际上是对整个表进行“分组”,所以数据库如何确定将浏览器的哪个值放入第一列?它不能。一些实现不会运行此查询,其他实现会或多或少随机选择浏览器值(这就是您所看到的)。

    【讨论】:

      【解决方案3】:

      COUNT(field) 消除空值。 SQL Server 还支持该命令的一些more flavors,不确定它们是否是标准的:

      COUNT(*) 返回组中的项目数,包括 NULL 值和重复项。

      COUNT(ALL expression) 计算组中每一行的表达式并返回非空值的数量。

      COUNT(DISTINCT expression) 计算组中每一行的表达式并返回唯一的非空值的数量。

      关于你的第二个问题,groupby 基本上是告诉聚合算子按某个字段对他们的操作进行分组。正如您所注意到的,如果您不指定分组字段,它们会在整个表上进行操作。 A little more from technet.

      我不确定结果 3 发生了什么,因为它在我看来不是有效的 SQL。通常,您不能将 COUNT 或 AVG 之类的聚合与非聚合字段混合在一起,除非您对这些字段进行分组。

      【讨论】:

        【解决方案4】:

        count(*) 表示要计算所有行。 count(browser) 表示要计算所有 non-null 浏览器值。这可能会产生重大影响,特别是如果您的浏览器列上没有索引,因为随后必须执行表扫描。

        group by 根据指定的列细分您的计数。

        【讨论】:

          【解决方案5】:

          COUNT(*) 通常是计算所有记录的简写。一些 RDBMS 对其进行了优化,例如 MySQL MyISAM 表。否则,COUNT(column_name) 对于非 NULL 值没有什么不同。

          您的第三个查询有所不同,因为您仍在对记录进行计数,但由于您没有按列对它们进行分组,因此您获得了所有记录的计数。在您的情况下,不仅仅是 Firefox 3 (14) 和 Unknown (11) 等于 25。返回您的第一行的事实很奇怪,并且正如其他用户所指出的那样,它可能不起作用。最终,这在很大程度上取决于您的 RDBMS。

          不确定您使用的是哪个 RDBMS,但您可以阅读 GROUP BY here。一般来说,虽然它们最常用于支持聚合函数,例如COUNT()、MAX()、AVG() 等。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-10-12
            • 1970-01-01
            • 1970-01-01
            • 2012-06-24
            • 1970-01-01
            • 2016-05-05
            相关资源
            最近更新 更多