问题
My laravel eloquent is like this :
$products = Product::where('status', 1)
->where('stock', '>', 0)
->where('category_id', '=', $category_id)
->groupBy('store_id')
->orderBy('updated_at', 'desc')
->take(4)
->get();
When executed, there exist error like this :
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'myshop.products.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by (SQL: select * from
products
wherestatus
= 1 andstock
> 0 andcategory_id
= 5 group bystore_id
order byupdated_at
desc limit 4)
How can I solve it?
回答1:
I had a similar Problem and solved it by disabling mysql strict mode in the database connection setting.
'connections' => [
'mysql' => [
// Behave like MySQL 5.6
'strict' => false,
// Behave like MySQL 5.7
'strict' => true,
]
]
You can find even more configuration settings in this blog post by Matt Stauffer
回答2:
In folder config => database.php make sure mysql strict is false, like this
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
if strict is true, make it false then clear config cash by run this command in cmd
php artisan config:clear
回答3:
I solved this problem by adding the "modes" option and setting only the modes I want to be enabled in config => database.php
'mysql' => [
...
'modes' => [
'STRICT_ALL_TABLES',
'ERROR_FOR_DIVISION_BY_ZERO',
'NO_ZERO_DATE',
'NO_ZERO_IN_DATE',
'NO_AUTO_CREATE_USER',
],
],
See more details in this tutorial
回答4:
That's because latest versions of MySQL behave like most dbms already do regarding group by
clauses; the general rule is
if you're using
group by
, all columns in yourselect
must be either present in thegroup by
or aggregated by an aggregation function (sum
,count
,avg
and so on)
Your current query is grouping by store_id
, but since you're selecting everything the rule above is not respected.
回答5:
In the .env file ADD variable: DB_STRICT=false
.
And REPLACE in file from the location: config/database.php, next codes 'strict' => true
ON
'strict' => (env('DB_STRICT', 'true') === 'true' ? true : false)
.
good luck.
回答6:
set
'strict' => false
in your config/database.php file. In array connections => mysql =>
in my case I'm using mysql 5.7 Laravel 5.7
回答7:
I solved it by setting modes in config/database.php file.
Set modes as follows:
'modes' => [
'STRICT_TRANS_TABLES',
'NO_ZERO_IN_DATE',
'NO_ZERO_DATE',
'ERROR_FOR_DIVISION_BY_ZERO',
'NO_ENGINE_SUBSTITUTION',
]
for mysql driver
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
'modes' => [
'ONLY_FULL_GROUP_BY',
'STRICT_TRANS_TABLES',
'NO_ZERO_IN_DATE',
'NO_ZERO_DATE',
'ERROR_FOR_DIVISION_BY_ZERO',
'NO_ENGINE_SUBSTITUTION',
]
],
回答8:
Check the query:
Product::where('status', 1)
->where('stock', '>', 0)
->where('category_id', '=', $category_id)
->groupBy('store_id')
->orderBy('updated_at', 'desc')
->take(4)
->get();
here you are grouping the data by store_id
and fetching all columns in the result set which is not allowed. To solve it either select store_id
or aggregate function on it or change the system variable sql_mode=only_full_group_by
to SET sql_mode = ''
.
Reference
回答9:
#Have the following method in your helper file
if (!function_exists('set_sql_mode')) {
/**
* @param string $mode
* @return bool
*/
function set_sql_mode($mode = '')
{
return \DB::statement("SET SQL_MODE=''");
}
}
Then call set_sql_mode(''); just before eloquent/query
回答10:
To select only aggregated columns, use the one of the raw methods provided by Laravel. For example:
Product::selectRaw('store_id')
->where('status', 1)
->groupBy('store_id')
->get();
回答11:
As said, set strict mode to false may give security bugs, what i am doing is to set sql_mode to empty before queries that require it. Note that it is a TEMPORARY change, once your connection is close (by laravel request) you will be set to original sql_mode=only_full_group_by (or beyond).
DB::statement("SET sql_mode = '' ");
Cheers, happy coding...
ps.: its not laravel fault, if you try to execute this query directly on your DB you will face same result. This work around works in mysql as well as first statement and again, will be a temporary session change, not permanent.
来源:https://stackoverflow.com/questions/43776758/how-can-i-solve-incompatible-with-sql-mode-only-full-group-by-in-laravel-eloquen