Bug #13160 Incorrect result with MIN and GROUP BY after DELETE and re-INSERT of same data
Submitted: 14 Sep 2005 0:40 Modified: 14 Sep 2005 5:23
Reporter: Daniel Nichter Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.1.14 OS:Linux (Linux Fedora Core 4)
Assigned to: CPU Architecture:Any

[14 Sep 2005 0:40] Daniel Nichter
Description:
Very briefly:
1. INSERT data A..Z
2. SELECT w/MIN and GROUP BY some of data X
3. Correct result is returned
4. DELETE from data just X
5. INSERT data X again
6. Run same query as #2 again
7. Incorrect result is returned

Longer example. "/tmp/bug" is all the data (i.e., A..Z). "/tmp/bug2" is a sub-set of /tmp/bug (i.e., X):
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> describe Host_Hits;
+-----------+--------------------------+------+-----+---------+----------------+
| Field     | Type                     | Null | Key | Default | Extra          |
+-----------+--------------------------+------+-----+---------+----------------+
| id        | int(10) unsigned         |      | PRI | NULL    | auto_increment |
| ymd       | int(10) unsigned         |      |     | 0       |                |
| hms       | int(6) unsigned zerofill |      |     | 000000  |                |
| host_id   | int(10) unsigned         |      |     | 0       |                |
| hit       | varchar(255)             |      |     |         |                |
| status    | smallint(5) unsigned     |      |     | 0       |                |
| bytes     | int(10) unsigned         | YES  |     | 0       |                |
| ref_id    | int(10) unsigned         | YES  |     | NULL    |                |
| username  | varchar(64)              | YES  |     | NULL    |                |
| se_hit_id | int(10) unsigned         | YES  |     | NULL    |                |
+-----------+--------------------------+------+-----+---------+----------------+
10 rows in set (0.06 sec)

mysql> show indexes from Host_Hits;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table     | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Host_Hits |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.00 sec)

mysql> load data infile '/tmp/bug' into table Host_Hits;
Query OK, 551 rows affected (0.09 sec)
Records: 551  Deleted: 0  Skipped: 0  Warnings: 0

mysql> select * from Host_Hits where ymd=20050912 and host_id=42 order by hms;
+-----+----------+--------+---------+---------------+--------+-------+--------+----------+-----------+
| id  | ymd      | hms    | host_id | hit           | status | bytes | ref_id | username | se_hit_id |
+-----+----------+--------+---------+---------------+--------+-------+--------+----------+-----------+
| 216 | 20050912 | 154425 |      42 | /             |    200 |  3110 |   NULL | NULL     |      NULL |
| 217 | 20050912 | 154435 |      42 | /             |    200 |  3110 |   NULL | NULL     |      NULL |
| 218 | 20050912 | 154449 |      42 | /             |    200 |  3110 |   NULL | NULL     |      NULL |
| 219 | 20050912 | 154512 |      42 | /mysqlreport  |    200 |  4467 |     15 | NULL     |      NULL |
| 220 | 20050912 | 154519 |      42 | /mysqlprofile |    200 |  2919 |     26 | NULL     |      NULL |
| 221 | 20050912 | 154523 |      42 | /optimize     |    200 |  2248 |     27 | NULL     |      NULL |
| 222 | 20050912 | 154539 |      42 | /optimize     |    200 |  2248 |     28 | NULL     |      NULL |
| 223 | 20050912 | 154545 |      42 | /intricacies  |    200 |  2226 |     28 | NULL     |      NULL |
| 224 | 20050912 | 154547 |      42 | /scripts/     |    200 |  2236 |     33 | NULL     |      NULL |
| 225 | 20050912 | 154552 |      42 | /feedback     |    200 |  1560 |     33 | NULL     |      NULL |
| 226 | 20050912 | 154557 |      42 | /consult      |    200 |  2035 |     36 | NULL     |      NULL |
| 227 | 20050912 | 154618 |      42 | /             |    200 |  3110 |     39 | NULL     |      NULL |
+-----+----------+--------+---------+---------------+--------+-------+--------+----------+-----------+
12 rows in set (0.05 sec)

mysql> SELECT ref_id, se_hit_id, MIN(hms) FROM Host_Hits WHERE ymd=20050912 AND host_id=42 GROUP BY host_id;
+--------+-----------+----------+
| ref_id | se_hit_id | MIN(hms) |
+--------+-----------+----------+
|   NULL |      NULL |   154425 |
+--------+-----------+----------+
1 row in set (0.06 sec)

mysql> delete from Host_Hits where ymd=20050912;
Query OK, 442 rows affected (0.09 sec)

mysql> load data infile '/tmp/bug2' into table Host_Hits;
Query OK, 442 rows affected (0.09 sec)
Records: 442  Deleted: 0  Skipped: 0  Warnings: 0

mysql> SELECT ref_id, se_hit_id, MIN(hms) FROM Host_Hits WHERE ymd=20050912 AND host_id=42 GROUP BY host_id;
+--------+-----------+----------+
| ref_id | se_hit_id | MIN(hms) |
+--------+-----------+----------+
|     39 |      NULL |   154425 |
+--------+-----------+----------+
1 row in set (0.06 sec)

mysql> \q

That last SELECT, where ref_id is returned as 39 is incorrect, as can be seen from the SELECT *, the record where hms is 154425 has NULL for ref_id.

Background info:
ymd and hms is a chopped up timestamp, Year-Month-Day, Hour-Minute-Second. host_id is a unique ID for whatever host. The idea is to select the first record for a given host on a given day.

Workaround:
SELECT ref_id, se_hit_id, hms FROM Host_Hits WHERE ymd=20050912 AND host_id=42 ORDER BY hms LIMIT 1;

Attached are min_bug.sql to create the exact table I'm using, min_bug-data_all.txt (aka /tmp/bug), and min_bug-data_20050912 (aka /tmp/bug2).

How to repeat:
1. Load min_bug.sql
2. Load infile min_bug-data_all.txt
3. SELECT ref_id, se_hit_id, MIN(hms) FROM Host_Hits WHERE ymd=20050912 AND host_id=42 GROUP BY host_id;
4. delete from Host_Hits where ymd=20050912;
5. Load infile min_bug-data_20050912.txt
6. SELECT ref_id, se_hit_id, MIN(hms) FROM Host_Hits WHERE ymd=20050912 AND host_id=42 GROUP BY host_id;
[14 Sep 2005 0:42] Daniel Nichter
.sql file to create the exact table the problem occurs with

Attachment: min_bug.sql (text/plain), 459 bytes.

[14 Sep 2005 0:42] Daniel Nichter
All the test data (a couple days worth of data)

Attachment: min_bug-data_all.txt (text/plain), 29.02 KiB.

[14 Sep 2005 0:43] Daniel Nichter
A sub-set of data (one particular day of data)

Attachment: min_bug-data_20050912.txt (text/plain), 22.27 KiB.

[14 Sep 2005 5:23] Hartmut Holzgraefe
Not a bug, see "GROUP BY with Hidden Fields"
http://dev.mysql.com/doc/mysql/en/group-by-hidden-fields.html

"Do not use this feature if the columns you omit from the GROUP BY part are not unique in the group! You get unpredictable results."
[13 Feb 2009 0:03] MySQL Verification Team
Bug: http://bugs.mysql.com/bug.php?id=42810 has been marked as duplicate of this one.