1. 程式人生 > >Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated colum

Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated colum

這個錯誤發生在mysql 5.7.5 和以後上,因為5.7.5預設的sql模式配置是

ONLY_FULL_GROUP_BY, 

這個配置啟用的是 “嚴格ANSIsql 規則”,嚴格ANSI sql 規則要求在group by的時候,沒有聚合的列,在group by的時候,必須全部包含在group by 的欄位中。

沒有聚合的列,指的是沒有使用 max, min, count, sum....這些函式的列,直接查詢出欄位的列。

如果不是aggregate 的列,必須要全部包含在集合裡面。aggregate 的列,指的大概就是不能聚合的列,沒有用函式的列,比如說 avg, sum, count 這些函式的列。

用了這些函式的列,可以不包含

英文摘要如下:

When MySQL's only_full_group_by mode is turned on, it means that strict ANSI SQL rules will apply when using GROUP BY. With regard to your query, this means that if you GROUP BY of the proof_type column, then you can only select two things: 
the proof_type column, or aggregates of any other column

Use ANY_VALUE() to refer to the nonaggregated column.


From MySQL 5.7 docs:


You can achieve the same effect without disabling ONLY_FULL_GROUP_BY by using ANY_VALUE() to refer to the nonaggregated column.


...


This query might be invalid with ONLY_FULL_GROUP_BY enabled because the nonaggregated address column in the select list is not named in the GROUP BY clause:


SELECT name, address, MAX(age) FROM t GROUP BY name;
...


If you know that, for a given data set, each name value in fact uniquely determines the address value, address is effectively functionally dependent on name. To tell MySQL to accept the query, you can use the ANY_VALUE() function:


SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;

實際上,在sql規則中,也是一直這麼說的,“除聚集計算語句之外,select語句中的每個列,都必須在group by 語句中給出”


上圖來源 https://cxiaodian.gitbooks.io/mysql/content/chapter9.html

不過按照官方文件的這麼講,我試了一下,好像沒看到什麼區別???

create table test_group_by(
name varchar(20),
address varchar(50),
age int 
)engine=innodb charset utf8;




INSERT INTO `easyspider`.`test_group_by` (`name`, `address`, `age`) VALUES ('a', 'a', '22');
INSERT INTO `easyspider`.`test_group_by` (`name`, `address`, `age`) VALUES ('b', 'b', '22');
INSERT INTO `easyspider`.`test_group_by` (`name`, `address`, `age`) VALUES ('c', 'c', '20');
INSERT INTO `easyspider`.`test_group_by` (`name`, `address`, `age`) VALUES ('a', 'a', '25');
INSERT INTO `easyspider`.`test_group_by` (`name`, `address`, `age`) VALUES ('b', 'b', '25');

select name, address, max(age)
from test_group_by
group by name, address;



select name, any_value(address), max(age)
from test_group_by
group by name;


set sql_mode='NO_ENGINE_SUBSTITUTION';

select name, address, max(age)
from test_group_by
group by name;


具體的原因如下:


參考連結:

https://stackoverflow.com/questions/41887460/select-list-is-not-in-group-by-clause-and-contains-nonaggregated-column-inc

https://stackoverflow.com/questions/34115174/error-related-to-only-full-group-by-when-executing-a-query-in-mysql

http://dict.youdao.com/w/aggregate%20/#keyfrom=dict2.top

https://stackoverflow.com/questions/37951742/1055-expression-of-select-list-is-not-in-group-by-clause-and-contains-nonaggr/37951813