Преди MySQL 5.7 по подразбиране се разрешава неПЪЛНА group by . Което означава, че можете да имате група от (която използва агрегатни функции като sum и max и count и group_concat ) с други неагрегирани колони (нека ги наречем NON AGGS ) като първите ви 3 показани не всички част от вашата group by клауза. Позволява го, но резултатите обикновено се получават по следния начин:
-
Сработи чудесно, защото познавате добре данните си и се опитвате да постигнете ясно
-
Получи се ужасно, защото беше гадно
Преди 5.7, ONLY_FULL_GROUP_BY съществуваше, но беше изключено по подразбиране.
Така че в MySQL 5.7 идва ONLY_FULL_GROUP_BY по подразбиране ВКЛ. Като такъв, ако опитате група от, но с не всички NON AGGS в group by клауза, ще получите грешка.
Помислете за следния проблем в 5.6 по-долу:
create table thing
( col1 int not null,
col2 int not null,
age int not null
);
insert thing(col1,col2,age) values
(1,2,10),
(1,3,20),
(2,3,20),
(2,2,10);
select col1,col2,max(age) from thing group by col1;
+------+------+----------+
| col1 | col2 | max(age) |
+------+------+----------+
| 1 | 2 | 20 |
| 2 | 3 | 20 |
+------+------+----------+
Това, което се случва по-горе, не е всичко NON AGGS са в group by . Връща max(age) от col1. Но тъй като col2 не беше в group by , той използва Cluster Index или Physical Ordering и му донесе, може би по невнимание (една грешка, грешка), грешна стойност за col2. В зависимост от вашите намерения или познаване на вашите данни или дори грижа. Двигателят не го интересуваше; може би го правиш.
За да избегне тези често срещани грешки или неволно връщане на данни, MySQL 5.7 включва ONLY_FULL_GROUP_BY по подразбиране.
Във вашия случай грешните редове съставляват резултатите ви вероятно за колони 2 и 3.
Вижте страницата наръчник, озаглавена Обработка на MySQL на GROUP BY .
Пример 2
-- drop table if exists person;
create table person
( id int auto_increment primary key,
firstName varchar(100) not null,
lastName varchar(100) not null
);
-- drop table if exists fruitConsumed;
create table fruitConsumed
( id int auto_increment primary key,
theDate date not null,
fruitId int not null, -- does not really matter. Say, 1=apple, 2=orange from some other table
personId int not null,
qty int not null
);
-- truncate table person;
insert person (firstName,lastName) values
('Dirk','Peters'),
('Dirk','Smith'),
('Jane','Billings');
-- truncate table fruitConsumed;
insert fruitConsumed (theDate,fruitId,personId,qty) values
('2016-10-31',1,1,2),
('2016-10-31',2,1,5),
('2016-10-31',2,2,12),
('2016-11-02',2,2,3);
Запитване:
select p.firstName,p.lastName,sum(fc.qty)
from person p
join fruitConsumed fc
on fc.personId=p.id
group by p.firstName,p.lastName;
+-----------+----------+-------------+
| firstName | lastName | sum(fc.qty) |
+-----------+----------+-------------+
| Dirk | Peters | 7 |
| Dirk | Smith | 15 |
+-----------+----------+-------------+
Горното работи чудесно на MySQL 5.6 и 5.7 независимо от настройката за ONLY_FULL_GROUP_BY
сега помислете
select p.firstName,p.lastName,sum(fc.qty)
from person p
join fruitConsumed fc
on fc.personId=p.id
group by p.firstName;
+-----------+----------+-------------+
| firstName | lastName | sum(fc.qty) |
+-----------+----------+-------------+
| Dirk | Peters | 22 |
+-----------+----------+-------------+
Горното често е приемливо за MySQL 5.6 без ONLY_FULL_GROUP_BY активирано и не работи на 5.7 с ONLY_FULL_GROUP_BY активиран (грешка 1055). Горният изход е основно глупост. Но по-долу е обяснено донякъде:
Знаем, че Дърк, един Дърк, само един Дърк, е единственият, който оцелява във вътрешното присъединяване. Има 2 Dirks. Но заради group by p.firstName , остава ни само един Дирк. Нуждаем се от lastName . Поради несъответствието с
SQL стандарта, MySQL може да позволи това с ONLY_FULL_GROUP_BY изключен. Така че просто избира всяко старо фамилно име. Е, първият, който намери, и това е или в кеша, или във физическото подреждане.
И това мина с Питърс. Сумата за броя на плодовете е за всички Dirks.
Така че, ако кодирате по този начин, несъответстващият не-ONLY_FULL_GROUP_BY ви дава глупости.
И както беше посочено, MySQL 5.7 по подразбиране не позволява това. Но може да се настрои по стария начин, ако решите.
Силно препоръчително е да коригирате заявките си и да напуснете ONLY_FULL_GROUP_BY както е активирано.