组上的 MySQL COUNT() 返回错误的行数

Posted

技术标签:

【中文标题】组上的 MySQL COUNT() 返回错误的行数【英文标题】:MySQL COUNT() on groups returns wrong number of rows 【发布时间】:2013-06-15 17:16:13 【问题描述】:

我有这张表叫做“值”:

value
12
13
5
56
3
56
79
98
58
74
52
2
8
32
4

我想得到每个 5 块的最小值,所以我尝试了这个查询:

SET @a = -1;
SELECT FLOOR((@a:=@a+1)/5) AS block, MIN(value)
FROM values
GROUP BY block

好像这个查询不包括每个块中的最后一行,所以我尝试了计数:

SET @a = -1;
SELECT FLOOR((@a:=@a+1)/5) AS block, COUNT(value)
FROM values
GROUP BY block

返回:

block    COUNT(value)
0        4
1        4
2        4

这里发生了什么?

【问题讨论】:

原因可能在此线程中解释:osdir.com/ml/mysql/2009-01/msg00002.html。你自己解释过吗? 【参考方案1】:

试试这个:

SELECT FLOOR(id/5) AS block, MIN(`value`)
FROM (SELECT (@id:=@id+1) AS id, `value`
      FROM `values`, (SELECT @id:=-1) AS A) AS B
GROUP BY block;

【讨论】:

感谢您的回答。我的示例可能有点令人困惑,因为我的真实表中的 id 与值不对应。我添加了 id 列只是为了说明块大小。我将编辑我的问题并删除 id 列以使其更清晰【参考方案2】:

这是来自MySQL 5.7 documentation 的一个 sn-p,应该会有所帮助:

在 SELECT 语句中,每个选择表达式仅在发送到客户端时才被计算。这意味着在 HAVING、GROUP BY 或 ORDER BY 子句中,引用在选择表达式列表中分配了值的变量不能按预期工作:

mysql> SELECT (@aa:=id) AS a, (@aa+3) AS b FROM tbl_name HAVING b=5;

HAVING 子句中对 b 的引用指的是选择列表中使用 @aa 的表达式的别名。这没有按预期工作:@aa 包含上一个选定行的 id 值,而不是当前行。

您的查询使用block 作为GROUP_BY 子句中的表达式,其中block 是赋值的结果,因此您的情况类似于MySQL 文档中的情况。鉴于您“落后一分”,它看起来确实很有希望!

运行解释可能会准确地告诉您发生了什么;试试这个可能是一个很好的练习。

【讨论】:

以上是关于组上的 MySQL COUNT() 返回错误的行数的主要内容,如果未能解决你的问题,请参考以下文章

MySQL利用count()函数统计总数的技巧

mysql中的count()函数

如何计算联接表上的行数

mysql性能优化------获取mysql的行数多少

mysql的count()

PHP MySQL 相同的查询返回不同的行数