我在数据库pet
中有以下表menagerie
:
+--------+-------------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+-------------+---------+------+------------+------------+
| Tommy | Salman Khan | Lebre | NULL | 1999-01-13 | 0000-00-00 |
| Bowser | Diane | dog | m | 1981-08-31 | 1995-07-29 |
+--------+-------------+---------+------+------------+------------+
现在如果我运行以下查询:
select owner, curdate() from pet;
我得到以下输出:
+-------------+------------+
| owner | curdate() |
+-------------+------------+
| Salman Khan | 2016-09-12 |
| Diane | 2016-09-12 |
+-------------+------------+
输出显示owner
的所有值,以及每行curdate()
返回的值。
现在,如果我运行以下查询:
select owner, count(*) from pet;
我得到以下输出:
+-------------+----------+
| owner | count(*) |
+-------------+----------+
| Salman Khan | 2 |
+-------------+----------+
我的问题是curdate()
和count()
函数之间的区别是什么让MySQL
输出第一个owner
Diane 示例
答案 0 :(得分:56)
COUNT()
是一个聚合函数,通常与GROUP BY
子句结合使用。
curdate()
是一个输出当前日期的日期函数。
只有MySQL(据我所知)在不使用GROUP BY
子句的情况下允许使用此语法。由于您没有提供,COUNT(*)
将计算表格中的总行数,owner
列将随机选择/优化程序默认/索引。
这应该是您的查询:
select owner, count(*)
from pet
group by owner;
告诉优化器计算总行数,每个所有者。
当没有提到group by子句时 - 聚合函数应用于表的整个数据。
编辑:对每行应用的计数通常不会使用COUNT()
完成,并且通常与分析函数一起使用 - >遗憾的是,COUNT() OVER(PARTITION...)
在MySQL中并不存在。您的另一个选择是为此附加列生成JOIN/CORRELATED QUERY
。
另一个编辑:如果您希望每个所有者旁边的总计数,您可以使用子查询:
SELECT owner,
(SELECT COUNT(*) FROM pet) as cnt
FROM pet
答案 1 :(得分:8)
这看起来与本页底部的方案完全相同:MySQL Documentation: 4.3.4.8 Counting Rows。
如果未启用ONLY_FULL_GROUP_BY,则处理查询 将所有行视为一个组,但为每个组选择的值 命名列是不确定的。服务器可以自由选择值 从任何一行:
mysql> SET sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> SELECT owner, COUNT(*) FROM pet; +--------+----------+ | owner | COUNT(*) | +--------+----------+ | Harold | 8 | +--------+----------+ 1 row in set (0.00 sec)
我想在这种情况下only_full_group_by
未设置。
答案 2 :(得分:4)
只有MySQL才能让你进行这种查询。
您应始终在GROUP BY
子句中指定未与聚合函数组合的所有列。如果没有,数据将合并为1行,聚合列设置正确,所有其他列随机或使用索引选择。
所以你需要这个:
SELECT owner, count(*) FROM pet GROUP BY owner;
将导致:
Saknan Khan | 1
Diane | 1
这是你打算实现的目标吗?
或许你试过这样做:
SELECT t.owner,
COUNT(*) as cnt
FROM pet t
CROSS JOIN pet s
GROUP BY t.owner
这会产生一个额外的列,其中包含每个所有者旁边的总计数。
答案 3 :(得分:2)
大多数DBMS系统不允许像count()这样的聚合函数以及没有group by的其他列;因为某种原因。 DBMS不知道要分组的列: - )。
解决方案是按所有者列对查询进行分组,如下所示:
SELECT owner, count(*) FROM pet GROUP BY owner;
答案 4 :(得分:2)
计数(*)聚合函数它只返回一个值,即总行数。而 curdate()功能只是提供系统的当前日期。
答案 5 :(得分:2)
最后一个查询对Oracle无效:ORA-00937:不是单组函数。这意味着您需要GROUP BY子句。您在MySql实现中发现了一个漏洞。不要在生产系统中依赖这样的查询,在下一版本的MySql中,这可能不起作用。
答案 6 :(得分:0)
是的,这通常不使用group by子句。
http://www.w3schools.com/sql/sql_groupby.asp您应该在链接中阅读有关group by子句的所有信息。
所有列都应该被提及聚合或分组