79

my Query :

select libelle,credit_initial,disponible_v,sum(montant) as montant 
FROM fiche,annee,type where type.id_type=annee.id_type and annee.id_annee=fiche.id_annee 
and annee = year(current_timestamp) GROUP BY libelle order by libelle asc
  • Mysql 5.7.9 runs the query without any problem but mysql 5.7.12 display the error above Could you please help me with that
4

12 Answers 12

113

I had a struggle getting this to work i've tested it and it's working on lamp server mysql version 5.12

So, steps to success:

  1. sudo vim /etc/mysql/conf.d/mysql.cnf
  2. Scroll to the bottom of file Copy and paste

    [mysqld] sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

to the bottom of the file

  1. save and exit input mode
  2. sudo service mysql restart to restart MySQL.

Done!

7
  • 6
    I resolved the same issue by removing only: STRICT_TRANS_TABLES from the sql_mode= string in /etc/mysql/my.cnf in Ubuntu 16.04 (MySQL 5.7) and restarting mysql: systemctl restart mysql
    – Grant
    Commented Aug 25, 2016 at 20:21
  • 3
    For Those Who Cannot Find This File my file was called my.ini is the same as mysql.cnf
    – Radmation
    Commented Nov 19, 2016 at 19:48
  • 7
    There's some info in the documentation on what's going on here: https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html And a less drastic way of working around than editing mysql.cnf (or just fixing the sql as gr1zzly be4r and scaisEdge suggested): https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value Commented Jan 12, 2017 at 12:18
  • 1
    You can find the original value by executing this SQL before you change my.cnf: show global variables like 'sql_mode';
    – Henry
    Commented May 9, 2017 at 5:14
  • 5
    Don't confuse [mysqld] with [mysql] as I did.
    – Henry
    Commented May 6, 2018 at 0:18
75

This worked for me:

mysql -u root -p
mysql > SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

You might need sudo for the first step:

sudo mysql -u root -p
6
  • 3
    in the end this was the only thing that worked for me too
    – Xoundboy
    Commented Feb 23, 2017 at 18:27
  • 1
    I've come to think this solution only persists until mysql is restarted. The accepted solution is better.
    – Henry
    Commented May 9, 2017 at 5:13
  • 4
    Henry, the advantage this approach has is that it can be applied selectively. If you modify my.cnf, every app and DB on the server is affected. OTOH, if the app/account has privileges for SET GLOBAL (which is not assured but can be implemented), you can run this query from the app in the DB preparation phase before other queries are run. It has saved my bacon with a elderly legacy app that violated FULL_ORDER_GROUP_BY ... I simply call this as soon as the DB connection is initalized ... Commented May 18, 2017 at 19:31
  • 2
    if MySQL is restarted then the issue will arise again. so this is not a permanent fix.
    – Star
    Commented Mar 26, 2019 at 13:22
  • 1
    i use uniserverZero, open console and write that code, now working, thanks
    – matasoy
    Commented Jul 23, 2020 at 7:44
33

You need to specify all of the columns that you're not using for an aggregation function in your GROUP BY clause like this:

select libelle,credit_initial,disponible_v,sum(montant) as montant 
FROM fiche,annee,type where type.id_type=annee.id_type and annee.id_annee=fiche.id_annee 
and annee = year(current_timestamp) GROUP BY libelle,credit_initial,disponible_v order by libelle asc

The full_group_by mode basically makes you write more idiomatic SQL. You can turn off this setting if you'd like. There are different ways to do this that are outlined in the MySQL Documentation. Here's MySQL's definition of what I said above:

MySQL 5.7.5 and up implements detection of functional dependence. If the ONLY_FULL_GROUP_BY SQL mode is enabled (which it is by default), MySQL rejects queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are neither named in the GROUP BY clause nor are functionally dependent on them. (Before 5.7.5, MySQL does not detect functional dependency and ONLY_FULL_GROUP_BY is not enabled by default. For a description of pre-5.7.5 behavior, see the MySQL 5.6 Reference Manual.)

You're getting the error because you're on a version < 5.7.5

2
  • 1
    I'm on ubuntu mysql 5.7.12 any other option available because i have other queries that i need how to turn only full group by of Commented Jun 22, 2016 at 19:34
  • 5
    This is an actual solution if you are currently writing your db logic, since this will make your code more precise and reduce a lot of uncertainty in your output. Commented Jun 19, 2018 at 22:38
24

You can disable sql_mode=only_full_group_by by some command you can try this by terminal or MySql IDE

mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

I have tried this and worked for me. Thanks :)

2
  • 3
    if MySQL is restarted then the issue will arise again. so this is not a permanent fix.
    – Star
    Commented Mar 26, 2019 at 13:21
  • You could add this statement to your my.cnf file to make the setting change permanent. Commented Jul 17, 2023 at 22:01
20

Solution 1: Remove ONLY_FULL_GROUP_BY from mysql console

mysql > SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

you can read more here

Solution 2: Remove ONLY_FULL_GROUP_BY from phpmyadmin

Open phpmyadmin & select localhost
Click on menu Variables & scroll down for sql mode
Click on edit button to change the values & remove ONLY_FULL_GROUP_BY & click on save. 

click here to see image

3
  • 1
    Hi Tauqueer, Please format the mysql line as code. Also you are missing the link referring to additional reading material.
    – hakamairi
    Commented Jun 28, 2018 at 13:01
  • 3
    if MySQL is restarted then the issue will arise again. so this is not a permanent fix.
    – Star
    Commented Mar 26, 2019 at 13:21
  • SOLUTION IS NOT WORKING
    – Kamlesh
    Commented Jan 13, 2023 at 18:04
11

You have to aggregate by anything NOT IN the group by clause.

So,there are two options...Add Credit_Initial and Disponible_v to the group by

OR

Change them to MAX( Credit_Initial ) as Credit_Initial, MAX( Disponible_v ) as Disponible_v if you know the values are constant anyhow and have no other impact.

1
  • 1
    THIS is the correct way. Assigning a name to the Max value was the way to do it, thank you 6 years later
    – bonjonbovi
    Commented Sep 29, 2022 at 17:16
9

So let's fully understand, Let's say you have a query which works in localhost but does not in production mode, This is because in MySQL 5.7 and above they decided to activate the sql_mode=only_full_group_by by default, basically it is a strict mode which prevents you to select non aggregated fields.

Here's the query (works in local but not in production mode) :

SELECT post.*, YEAR(created_at) as year
FROM post
GROUP BY year

SELECT post.id, YEAR(created_at) as year  // This will generate an error since there are many ids
FROM post
GROUP BY year

To verify if the sql_mode=only_full_group_by is activated for, you should execute the following query :

SELECT @@sql_mode;   //localhost

Output : IGNORE_SPACE, STRICT_TRANS, ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION (If you don't see it, it means it is deactivated)

But if try in production mode, or somewhere where it gives you the error it should be activated:

SELECT @@sql_mode;   //production

Output: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO... And it's ONLY_FULL_GROUP_BY we're looking for here.

Otherwise, if you are using phpMyAdmin then go to -> Variables and search for sql_mode

Let's take our previous example and adapt it to it :

SELECT MIN(post.id), YEAR(created_at) as year  //Here we are solving the problem with MIN()
FROM post
GROUP BY year

And the same for MAX()

And if we want all the IDs, we're going to need:

SELECT GROUP_CONCAT(post.id SEPARATOR ','), YEAR(created_at) as year
FROM post
GROUP BY year

or another newly added function:

SELECT ANY_VALUE(post.id), YEAR(created_at) as year 
FROM post
GROUP BY year

⚠️ ANY_VALUE does not exist for MariaDB

And If you want all the fields, then you could use the same:

SELECT ANY_VALUE(post.id), ANY_VALUE(post.slug), ANY_VALUE(post.content) YEAR(created_at) as year 
FROM post
GROUP BY year

❌ To deactivate the sql_mode=only_full_group_by then you'll need to execute this query:

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));

Sorry for the novel, hope it helps.

7

Base ond defualt config of 5.7.5 ONLY_FULL_GROUP_BY You should use all the not aggregate column in your group by

select libelle,credit_initial,disponible_v,sum(montant) as montant 
FROM fiche,annee,type 
where type.id_type=annee.id_type 
and annee.id_annee=fiche.id_annee 
and annee = year(current_timestamp) 
GROUP BY libelle,credit_initial,disponible_v order by libelle asc
2
  • 1
    it does not make any sens, if you count by some id(index pointing to another table), then why would you need to add the other collumns that are not related to the counting in the group by, especialy if you dont want to group by these columns
    – Phil
    Commented Apr 27, 2017 at 6:04
  • 1
    @fdsfdsfdsfds This is what the clause forces you to do. ONLY_FULL_GROUP_BY requires all columns that are not managed by aggregation functions to be declared in the group by .. thse solution provided by the OP change the ONLY_FULL_GROUP_BY sql_mode but this is not sql correctly (also if is allwed by mysql until 5.7 by default)
    – ScaisEdge
    Commented Apr 27, 2017 at 6:11
4

Also if you use MySql 8+ try in console this command:

Open MySql console

mysql -u user_name -p

And set global SQL mode

SET GLOBAL sql_mode='STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_ENGINE_SUBSTITUTION';
0
1

Same thing is happened with 8.0+ versions as well. By default in 8.0+ version it is "enabled" by default. Here is the link official document reference

In case of 5.6+, 5.7+ versions, the property "ONLY_FULL_GROUP_BY" is disabled by default.

To disabled it, follow the same steps suggested by @Miloud BAKTETE

0

just go to the window bottom tray click on wamp icon ,click mysql->my.ini,then there is option ;sql-mode="" uncomment this make it like sql-mode="" and restart wamp worked for me

0

I don't recommend you change your

sql_mode=only_full_group_by

unless you know what you are doing.

Not putting all the aggregating columns into the group by is technically wrong, and can produce unexpected results. If you are someone that doesn't know that this is poor practice, it would be better to learn why this is poor practice and avoid it. Not to mention, if you start writing SQL for most other DBMS they won't let you write these types of queries either.

Not the answer you're looking for? Browse other questions tagged or ask your own question.