MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

时间:2023-03-09 09:56:14
MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

本文导读:在MYSQL中使用GROUP BY分组时,我们可以select 多个非聚合字段,但是这些字段不在GROUP BY中,这样的SQL查询在SQL SERVER、ORACLE中是不合理的,且会报错,MYSQL的这种特异性,有时查询出来的结果并不是我们需要的,那么,我们在使用时应该注意哪些呢?

一、下列语句在MySql中是合规的

select count(1),task_type,status from action where biz_date='20141014' group by status
select count(1),task_type from action where biz_date='20141014' group by status

二、使用时易出现的问题

1、实例数据

mysql> select * from test;
+----+-------+------+-------+
| id | name  | age  | class |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项+----+-------+------+-------+
MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  1 | qiu   |   22 |     1 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  2 | liu   |   42 |     1 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  4 | zheng |   20 |     2 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  3 | qian  |   20 |     2 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  0 | wang  |   11 |     3 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  6 | li    |    |     3 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

+----+-------+------+-------+
6 rows in set (0.00 sec)

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

2、找到每个class里面的最大的age的基本信息

如下的sql语句,则输出结果不准确

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项
mysql> select id,name,max(age),class from test group by class;

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

+----+-------+----------+-------+

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

| id | name  | max(age) | class |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

+----+-------+----------+-------+

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  1 | qiu   |       42 |     1 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  4 | zheng |       20 |     2 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

|  0 | wang  |       |     3 |

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

+----+-------+----------+-------+

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

3 rows in set (0.00 sec)

备注

虽然找到的age是最大的age,但是与之匹配的用户信息却不是真实的信息

原因

如果 id,name 不能唯一确定的话,mysql会随机选一行做为值。

三、使用是注意事项

1、这个写法不标准, 因为假如没group的字段如果有多个值, 可能导致这个字段会有不确定的值,且不利于数据库移植

2、假如可以确定这个字段都是重复的值(譬如多表联接), 那就没有这方面的困扰,反而会简化SQL语句,也有可能会提高性能,可以推荐这种方式查询

例如

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项
select A.id, B.desc, B.XXX, B.YYY SUM(A.AMT)

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

    FROM A

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

    join b on a.id=b.id

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

    where a.id=? and b.xxx=?

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

    group a.id

转载自:http://www.studyofnet.com/news/1233.html