Disable ONLY_FULL_GROUP_BY mode in mysql docker container - mysql

I have a big problem when I want to make a view.
CREATE VIEW AnneeBillet (ANNEE_BILLETS, CHIFFRES)
AS SELECT YEAR(FIN_RESERVATION), sum(TYPE.PRIX*NOMBRE)
FROM TYPE, BILLET
where TYPE.TYPE = BILLET.TYPE;
I have this error :
In aggregated query without GROUP BY, expression #1 of SELECT list
contains nonaggregated column 'parc.BILLET.FIN_RESERVATION'; this is
incompatible with sql_mode=only_full_group_by
I have already tried many solutions like putting
SET GLOBAL sql_mode=(SELECT REPLACE(##sql_mode,'ONLY_FULL_GROUP_BY',''));
But I'm with a docker container and I've seen that I had to modify directly the configuration file to have what I want.
Then, I found this post on stackoverflow but I can't do
--sql_mode=(SELECT REPLACE(##sql_mode,'ONLY_FULL_GROUP_BY',''))
in my docker-compose because I have an error like this :
mysql_1 | 2021-04-27T07:59:53.283400Z 0 [ERROR] [MY-000077]
[Server] /usr/sbin/mysqld: Error while setting value '(SELECT
REPLACE(##sql_mode,'ONLY_FULL_GROUP_BY',''))' to 'sql_mode'.
Please help me, I'm fed up with this problem.

Just add GROUP BY YEAR(FIN_RESERVATION) to the end of your query or change it to MIN(YEAR(FIN_RESERVATION)) - you can also use max. If you didn't do these things and instead changed the mode MySQL would simply arbitrarily pick one of the year values anyway
Only full group by is a good thing

If you permanently want to disable only_full_group_by on startup, you can add:
sql-mode= "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
To your my.ini or my.cnf under '[mysqld]'.
Also if you get the error:
"Error while setting value 'STRICT_TRANS_TABLES,​NO_ZERO_IN_DATE,​NO_ZERO_DATE,​ERROR_FOR_DIVISION_BY_ZERO,​NO_ENGINE_SUBSTITUTION' to 'sql_mode'"
as I did, you can get around this issue, by first clearing all sql-modes by putting sql-mode="" above:
sql-mode= "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

You can't use an sql expression as the value of --sql_mode. Run SET SESSION sql_mode=(SELECT REPLACE(##sql_mode,'ONLY_FULL_GROUP_BY','')); SELECT ##sql_mode; in your server and use the value it shows with --sql_mode.

Related

SET GLOBAL sql_mode no longer works, and setting doesn't exist in my.cnf

I am running MySQL 14.14 Distrib 5.7.40 for Linux (x86_64) on my BlueHost VPS. A few months ago I could run this command successfully:
SET GLOBAL sql_mode=(SELECT REPLACE(##sql_mode,'ONLY_FULL_GROUP_BY',''));
I have to go rerun this every few months to avoid this error:
...this is incompatible with sql_mode=only_full_group_by
Today when I ran that it appeared successful, but the SQL errors remain in my web app:
Invalid query: Expression #1 of ORDER BY clause is not in GROUP BY
clause and contains nonaggregated column
'MyDatabase.s.EventDate' which is not functionally dependent on
columns in GROUP BY clause; this is incompatible with
sql_mode=only_full_group_by
My full query that is breaking:
SELECT g.GroupID,
g.GroupName,
count(s.EventDate) AS Total
FROM Groups g
LEFT JOIN Schedule s ON g.GroupID = s.GroupID
JOIN Settings se ON g.GroupID = se.GroupID
WHERE g.OrganizationID = 479
AND g.IsActive = 1
AND IFNULL(g.IsDeleted, 0) = 0
AND IFNULL(g.IsHidden, 0) = 0
AND se.SettingName = 'HideGroupNoGames'
AND (s.EventDate > DATE_ADD(NOW(), INTERVAL 0 HOUR)
OR g.CreateDate > DATE_ADD(DATE_ADD(NOW(), INTERVAL -1 DAY), INTERVAL 0 HOUR)
OR se.SettingValue = 'False')
GROUP BY g.GroupID, g.GroupName
ORDER BY s.EventDate, g.GroupName
And when I run SET GLOBAL sql_mode=(SELECT REPLACE(##sql_mode,'ONLY_FULL_GROUP_BY',''));, the error doesn't go away.
I tried stopping and starting the mysqld service from terminal. Success, but SQL error remains.
When I run this: select ##sql_mode;, it still displays this:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Even though I already ran this:
SET GLOBAL sql_mode=(SELECT REPLACE(##sql_mode,'ONLY_FULL_GROUP_BY',''));
...and this:
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;
I would love to fix the SQL statement so the error goes away, but I don't know how. Whenever I tweak it I get different and incorrect results.
I learned from this SO post that SET GLOBAL is temporary and will reset when mysql restarts. But when I run cat my.cnf, I don't even see the sql_mode:
[mysqld]
performance-schema=0
default-storage-engine=MyISAM
interactive_timeout=300
key_cache_block_size=4096
max_heap_table_size=32M
max_join_size=1000000000
max_allowed_packet=268435456
open_files_limit=40000
query_cache_size=32M
thread_cache_size=100
tmp_table_size=32M
wait_timeout=7800
max_user_connections=50
myisam_recover_options=FORCE
innodb_file_per_table=1
innodb_flush_log_at_trx_commit=0
innodb_purge_threads=1
innodb_support_xa=0
innodb_thread_concurrency=8
pid-file=/var/lib/mysql/mysqld.pid
innodb_buffer_pool_size=55574528
I think perhaps any of the following solutions would work for me:
Why doesn't SET GLOBAL sql_mode work any more, and how can I make it work?
Why doesn't my.cnf contain anything about sql_mode?
How can I fix my query so the SQL mode doesn't matter, and doesn't error?
Okay, a couple of things are going on.
Using SET GLOBAL doesn't affect the current session in which you ran that statement. It changes the global option, but the current session still uses session values copied from the global values when the session starts. If you start a new session after you use SET GLOBAL, it will inherit the change.
You can change the current session's configuration with SET SESSION sql_mode=... or simply SET sql_mode=... which is equivalent.
Restarting mysqld discards any changes you made with SET GLOBAL, and reverts to the options in my.cnf (or the default value compiled-in to the mysqld executable, if the option is not specified in my.cnf). Simply changing the global option is not written to my.cnf.
In MySQL 8.0, you can use SET PERSIST to change the global value and write it to a file so it remains in effect if you restart mysqld. Read about this in more detail: https://dev.mysql.com/doc/refman/8.0/en/set-variable.html
Both of these things have been the way it worked for years. It's likely that it's working exactly as documented.
It's recommended that you should NOT change the sql mode. Your query can be changed to comply with the default sql mode.
Since EventDate is not a column in your GROUP BY clause, it may have multiple values per group. So it's undefined what happens if you ORDER BY s.EventDate, .... Which value in the group should it use to sort?
You should resolve this by sorting by a specific value in the group. For example, these would be acceptable choices:
ORDER BY MAX(s.EventDate), g.GroupName
ORDER BY MIN(s.EventDate), g.GroupName

#1055 - Expression of SELECT list is not in GROUP BY clause and contains nonaggregated column this is incompatible with sql_mode=only_full_group_by

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
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:
sudo vim /etc/mysql/conf.d/mysql.cnf
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
save and exit input mode
sudo service mysql restart to restart MySQL.
Done!
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
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
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 :)
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.
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.
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
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.
In Laravel, you just set false in file database.php.
...
'mysql' => [
...
'strict' => false,
...
]
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';
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
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

Doctrine Querybuilder ORDER BY clause is not in SELECT list

I have the following query builder:
$queryBuilder = $this
->createQueryBuilder('recipient')
->leftJoin('recipient.message', 'message')
->orderBy('message.dateSent', 'DESC');
This has been working fine :) - but since upgrading to Mysql 5.7 I have started getting this error everywhere:
SQLSTATE[HY000]:
General error: 3065
Expression #1 of ORDER BY clause is not in SELECT list, references column 'dctrn_result.date_sent_5' which is not in SELECT list;
this is incompatible with DISTINCT
I have solved this in most places where I am using the DBAL layer by just add the item to the select list, but I can't figure out how to do that with this particular queryBuilder.
You have to edit the /etc/mysql/mysql.cnf by adding these lines:
[mysqld]
sql-mode=""
Don't forget to restart the service mysql:
sudo service mysql restart
For info, I am using Ubuntu 16.04 LTS.
Adding:
[mysqld]
sql-mode=""
to /etc/mysql/my.cnf fixed the problem for me (after restarting service). Although of course an official response to the doctrine issue would be nicer.
Update: Someone who knows more than me about this recommended only disabling the mode that's causing the problem.
Actually mysql 5.7 contains 'ONLY_FULL_GROUP_BY' in sql mode.So we can't perform orderby in the element that is not in select list.we have to change it from
'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
into
'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
We can done this by executing the following queries
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'
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'
Thanks,
Suriya
There is a bug reported in #4846 and it seems to be related to #sqlmode_only_full_group_by and there are some examples abaut what does it mean here. Until a proper fix comes out a solution would be to add ->addSelect('message') to the query (I don't know if it fixes the issue or doctrine rewrites the query anyway), but that way doctrine will hydrate massages as well which maybe not desired or disable ONLY_FULL_GROUP_BY sql mode, but then, mysql maybe can return invalid data.
When using QueryBuilder, joined tables are not added to the select list automatically. You can call addSelect(TABLE_ALIAS) to get rid of the error.
$queryBuilder = $this
->createQueryBuilder('recipient')
->leftJoin('recipient.message', 'message')
->addSelect('message') //THIS LINE
->orderBy('message.dateSent', 'DESC');
Updating Doctrine to 2.8 should resolve this.

disable "unsafe statement for binary logging" In mysql

How do i disable unsafe statement for binary logging Warning Message in Error log in MySQL 5.5 version.
I don't want to change my binlog format to Row or Mixed Mode.
In Percona there is variable log_warnings_suppress = 1592
Is there anything like this in MySQL ?
Thanks,
Ash
If you are getting that from a DELETE with a LIMIT, there is a workaround.
Do a SELECT with the same ORDER BY and LIMIT to get the id or range of ids that need to be deleted.
Perform the DELETE with that id or IN ( ... ) or id BETWEEN ... AND ....
#ircmaxwell he isn't actually hiding the warning (in this case) he is suppressing a warning that is not a requirement for his set up. This is warning on an unsafe 'binary log statement', which could just be an update with a limit clause.. for example.
Its normally 'fixed' by setting replicatuion to 'row' or 'mixed'. If that is not wanted, then Percona came up with the solution to 'hide' it.

CaseSenstive Table names

hi there i made track star application and everything works fine except for one issue that i face error
CDbCommand failed to execute the SQL statement: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'devnmark_root.AuthAssignment' doesn't exist. The SQL statement executed was: SELECT *
FROM 'AuthAssignment'
WHERE userid=:userid
now this was automatically generated by Yii when i checked for if(Yii::app()->user->checkAccess('createUser',array('project'=>$model)))
18 {
19 $this->menu[] = array('label'=>'Add User To Project','url'=>array('adduser', 'id'=>$model->id));
20 }
then i went to phpmyadmin and executed this query manually
SELECT * FROMAuthAssignmentWHERE userid=4 and there is error which says same that table does not exist.
if i use small case letter for table name then no error.
i executed same query on local wamp 's phpmyadmin same query does not show any error there so this is clear that there is error with my sql .any idea what can i do to solve?
I suggest you hitting up SQL_MODE documentation for setting your final options. http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html
For testing you can just do a:
SET sql_mode = '';
Or adjust your command line:
--sql-mode=""
You may try to set the system variable *lower_case_table_names* to 1.
My local application was developed under Windows, howerver production is under Linux and I caused the same problem.
For me it happened because of case sensitivity - table AuthAssignment in database was actually authassignment.
I have found two options to solve it:
rename database table from authassignment to AuthAssignment
or
edit config file component section:
'components'=>array(
...
'user'=>array(...
),
'authManager'=>array(
...
'assignmentTable'=>'authassignment' //THIS LINE SOLVED MY PROBLEM
),
I had the same problem of non-existent authassignment table, I had forgotten running the rights installation which in my case was by following URL i.e.
/index.php/rights/install
and then the setup was like a breeze and self explanatory :)
For me this answer helped the most: original source.
In the authManager in config/main.php you can add lowercased names of the tables like this:
'components'=>array(
'authManager'=>array(
'defaultRoles'=>array('guest'),
'class'=>'RDbAuthManager',
'assignmentTable'=>'authassignment',
'itemTable'=>'authitem',
'rightsTable'=>'rights',
'itemChildTable'=>'authitemchild',
),