简体   繁体   中英

MySQL COUNT() on groups returns wrong number of rows

I have this table called "values":

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

I want to get the lowest value for each block of 5, so I tried this query:

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

It seems like this query does not include the last row in each block, so I tried count:

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

which returned:

block    COUNT(value)
0        4
1        4
2        4

what is happening here?

Try this:

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;

Here is a snippet from the MySQL 5.7 documentation that should help:

In a SELECT statement, each select expression is evaluated only when sent to the client. This means that in a HAVING, GROUP BY, or ORDER BY clause, referring to a variable that is assigned a value in the select expression list does not work as expected:

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

The reference to b in the HAVING clause refers to an alias for an expression in the select list that uses @aa. This does not work as expected: @aa contains the value of id from the previous selected row, not from the current row.

Your query uses block as the expression in the GROUP_BY clause, where block is the result of an assignment, so your situation is the analogous to the one from the MySQL documentation. It certainly looks promising, given that you are "off by one"!

Running an explain might tell you exactly what is happening; it will probably be a good exercise to try this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM