groupby和count如何在sql中工作

时间:2010-10-28 02:11:00

标签: sql mysql count group-by

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。 :)

5 个答案:

答案 0 :(得分:3)

选择关系会为您提供结果集。如果要按字段对选择进行分组,则结果集的行将按该字段分组,结果集的每一行将特定于结果组。

例如,您有一个名为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)插入一行,这是最好的测试。

答案 1 :(得分:2)

COUNT(*)通常是计算所有记录的简写。一些RDBMS对它进行了优化,就像MySQL MyISAM表一样。否则,COUNT(column_name)对于非NULL值没有区别。

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

不确定您使用的是哪种RDBMS,但您可以在GROUP BY here上阅读。一般来说,虽然它们最常用于支持汇总功能,例如COUNT()MAX()AVG()等。

答案 2 :(得分:0)

count(*)说要计算所有行数。 count(browser)表示计算所有非null 浏览器值。这可能会产生显着差异,特别是如果您的浏览器列上没有索引,因为必须执行表扫描。

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

答案 3 :(得分:0)

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

  

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

     

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

     

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

关于你的第二个问题,groupby基本上告诉聚合运营商按某个字段对其操作进行分组。正如您所注意到的,如果您未指定分组字段,则它们将在整个表上运行。 A little more from technet

我不确定结果3发生了什么,因为它对我来说看起来不像是有效的SQL。通常,您不能将COUNTAVG等聚合与非聚合字段混合使用,除非您对这些字段进行分组。

答案 4 :(得分:0)

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

那说:

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

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

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