简体   繁体   中英

MySQL : isn't in GROUP BY

The site produces results, but with SELECT COUNT and SELECT query with GROUP BY having two different result counts. This is likely due to the error that is displaying in phpmyadmin but not on the site.

The Queries:

SELECT count(DISTINCT `name`) as `numrows` FROM `users` WHERE `verified` = '1'

SELECT `name`, `type`, `language`, `code` FROM `users` WHERE `verified` = '1' GROUP BY `name` ORDER BY `count` DESC LIMIT 0, 25

PhpMyAdmin provides the following error:

1055 - 'main.users.type' isn't in GROUP BY

When reading MySQL docs, I'm still unclear what it is I have to fix. I can't seem to grasp this.

You need to have a full group by:

SELECT `name`, `type`, `language`, `code` 
FROM `users` 
WHERE `verified` = '1' 
GROUP BY `name`, `type`, `language`, `code` 
ORDER BY `count` DESC LIMIT 0, 25

SQL92 requires that all columns (except aggregates) in the select clause is part of the group by clause. SQL99 loosens this restriction a bit and states that all columns in the select clause must be functionally dependent of the group by clause. MySQL by default allows for partial group by and this may produce non-deterministic answers, example:

create table t (x int, y int);
insert into t (x,y) values (1,1),(1,2),(1,3);
select x,y from t group by x;
+------+------+
| x    | y    |
+------+------+
|    1 |    1 |
+------+------+

Ie a random y is select for the group x. One can prevent this behavior by setting @@sql_mode:

set @@sql_mode='ONLY_FULL_GROUP_BY';
select x,y from t group by x; 
ERROR 1055 (42000): 'test.t.y' isn't in GROUP BY

The best solution to this problem is, of course, using a complete GROUP BY expression.

But there's another solution that works around the ONLY_FULL_GROUP_BY blocking of the old MySQL extension to GROUP BY .

SELECT name, 
       ANY_VALUE(type) type,
       ANY_VALUE(language) language,
       ANY_VALUE(code) code 
  FROM users  
 WHERE verified = '1' 
 GROUP BY name 
 ORDER BY count DESC LIMIT 0, 25

ANY_VALUE() explicitly declares what used to be implicit in MySQL's incomplete GROUP BY operations -- that the server can choose, well, any, value to return.

Another solution mentioned multiple times above is to turn off that annoying 'ONLY_FULL_GROUP_BY' eg like in this post: Disable ONLY_FULL_GROUP_BY

I think this solution is very useful if you do not want to refactor the whole project for multiple hours. And if you do not care about the unpredictable values of the columns which are not list of the GROUP BY .

First thing is to see why it is like that. Earlier versions allowed us to be negligent a bit: while the values of the grouped column are completely listed (one from each without exceptions) in the result, values of the other selected column(s) are more or less omitted - but the code can't (does not want to) tell which ones on your behalf:

- Hey, MYSQL, list the families of the street - but add a first name as well to every row.
- Okay sir, but shall I use the father's or the mother's or...? I'm a machine, give exact orders!

Now that we understand the why, we can decide if we have preferences regarding the other column(s). Use

MAX() AS
MIN() AS
etc, works with strings, too

or if it's really all the same, eg there's no difference between the nonaggregated values that are related to the grouped one, use

ANY_VALUE() AS

Either way, you let mysql know that you're aware of being "equivocal" but you really don't want to focus on all the columns other than the one(s) you grouped.

只需禁用查询的严格性。

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