使用包含聚合函数的select语句的错误原因?

时间:2016-04-24 14:43:33

标签: mysql sql

如果我试图获取所有客户的名称以及客户总数,有人可以解释为什么以下查询会引发错误吗?

SELECT name, COUNT(*)
FROM CUSTOMER

我知道选择列和聚合函数需要包含所有列名的GROUP BY语句,但我不明白这背后的逻辑原理。

编辑:

http://sqlfiddle.com/#!2/90233/595 我猜'错误'不是很正确,但请注意当前查询如何将Allison 9作为唯一结果返回。 我不明白为什么不回来:

Alison 9

Alison 9

Alison 9

Alison 9

Jason 9

...

3 个答案:

答案 0 :(得分:0)

Select name, Count(*) as 'CountCustomers'
FROM CUSTOMER
Group by name
Order by name

将其视为指示聚合哪个字段的指令。例如,如果您有一个包含客户状态的字段,您可以按州分组,这将按州提供客户数。

另外,请注意,您可以使用" over(分隔为"构造。)来在同一个选择中使用多个聚合函数。

答案 1 :(得分:0)

如果您想要名称以及客户数,请使用窗口函数:

select name, count(*) as NumCustomersWithName,
       sum(count(*)) over () as NumCustomers
from customer
group by name;

编辑:

你实际上似乎想要:

select name, count(*) over () as NumCustomers
from customer;

在MySQL中,您可以使用子查询执行此操作:

select name, cnt
from customers cross join
     (select count(*) as cnt from customers) x;

您的查询不起作用的原因是因为它是一个只返回一行的聚合查询。当您使用没有GROUP BY的聚合函数时,查询始终只返回一行。

答案 2 :(得分:0)

(这是基于评论并查看小提琴的新答案。)

这里的问题是mysql如何处理聚合函数 - 这是一种非标准的方式,与其他人不同。

mysql允许你使用聚合函数(count()是聚合函数的一个例子)而没有group by。当您使用count(*)时,所有(或大多数?)其他sql实现都需要group by。当你有一个组时,你必须说出组中的范围(例如按名称分组)。 同样每列必须在聚合函数的范围或结果中。

由于你没有范围mysql假设整个表,并且因为你有一个不是聚合函数或范围(在这种情况下是名称)的结果的列,mysql会做一些事情来制作该列聚合函数的结果。我不确定它是否在mysql中指定了它的作用 - 让我们说" max()"。 (相当确定它是max())。所以正在执行的真正的SQL是

SELECT ANY_VALUE(name), COUNT(*)
FROM CUSTOMER

因此,您只能看到一个名字。

mysql文档 - http://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

阅读完上述内容后,我发现mysql将使用默认的聚合函数ANY_VALUE()来表示不在范围内的列。

如果您只想要每行的客户总数,您可以这样做

SELECT DISTINCT NAME, COUNT(NAME) OVER () AS CustomerCount
FROM CUSTOMER

通过这种方式,您不需要GROUP BY语法。在幕后,它可能和@GordonLinoff的回答一样。

我添加了这个,因为它可能会让群组更加清晰。