155

I want to use WhereIn and Groupby in the same query to fetch Result.

I've tried this:

$loadids=explode("#@*",$reciptdet->loading_id);
$loadingdatas=DB::table('loading')->groupBy('vehicle_no')->whereIn('id',$loadids)->get();

But I got this error message:

SQLSTATE[42000]: Syntax error or access violation: 1055 'sbrtpt.loading.id' isn't in GROUP BY (SQL: select * from loading where id in (14, 15, 16) group by vehicle_no)

Karthikvijayaveni
  • 1,864
  • 3
  • 13
  • 15

15 Answers15

359

Short answer

In config\database.php --> "mysql" array

Set 'strict' => false to disable all.

.... or

You can leave 'strict' => true and add modes to "mysql" option in

'mysql' => [
       ...
       ....
       'strict' => true,
       'modes' => [
            //'ONLY_FULL_GROUP_BY', // Disable this to allow grouping by one column
            'STRICT_TRANS_TABLES',
            'NO_ZERO_IN_DATE',
            'NO_ZERO_DATE',
            'ERROR_FOR_DIVISION_BY_ZERO',
            'NO_AUTO_CREATE_USER',
            'NO_ENGINE_SUBSTITUTION'
        ],
 ]

Detailed answer

You may not need to disable all strict options ... Kindly have a look on this answer about this issue.

Husam
  • 8,149
  • 3
  • 38
  • 45
  • How can we set this strict mode to false on oracle connection in laravel? Please help me – Vikas Chauhan May 13 '19 at 08:36
  • @VikasChauhan, Sorry I didn't use Oracle before – Husam May 13 '19 at 15:23
  • 6
    This worked!!! For anybody who is still getting the same error after changing that setting, try clearing the config cache by running `php artisan config:cache` – Altin Oct 27 '19 at 16:43
  • 4
    My concern about this kind of hard-coded workaround is that I feel some kind of technical debt that will not make me sleep well at night, because the kind of questions that will be floating in my head will be like: what happens when Laravel and/or MySQL spec changes wrt the `modes` (e.g. addition/removal of some of the modes specified in that array, or worse still, the name of one of the modes specified in that array changes). So, I just leave `strict=true` and won't touch any `mode` thing. I'll rather update my code to work with such strict setting. `ThisPractice === SleepWellEveryNight` :) – Damilola Olowookere Feb 09 '20 at 15:40
  • 1
    @Husam may I know what is the pros and cons disabling strict? Thanks for the answer – Mathew Magante Feb 26 '20 at 15:39
  • 2
    A much better solution is write better SQL – Chuck Le Butt Jul 14 '20 at 21:06
  • 1
    I wasted hours messing with different things, attempting to set the permission globally and had no idea that config option was available! – Adam Patterson May 11 '22 at 20:05
123

This is probably a SQL_MODE problem. In your config/database.php, in the connection, change

strict => false

As in

'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' => false,
    'engine' => null,
],
Antonio Carlos Ribeiro
  • 86,191
  • 22
  • 213
  • 204
43

No need to change any where in your System jut use code like in laravel

\DB::statement("SET SQL_MODE=''");//this is the trick use it just before your query

$data=Task::where('user_id', Auth::user()->id)->where('status', 0)->groupBy('task_code')->get(['id','task_code', 'title']);
Sk Bindas
  • 699
  • 7
  • 4
16

Without modifiying config\database.php file

Set 'strict' => false in the config\database.php could be a security issue. So, a simple Laravel solution could be first call get() and then groupBy('vehicle_no):

$loadids = explode("#@*", $reciptdet->loading_id);
$loadingdatas = DB::table('loading')->whereIn('id', $loadids)->get();
$grouped = $loadingdatas->groupBy('vehicle_no');
cespon
  • 5,630
  • 7
  • 33
  • 47
  • I couldn't get proper result when 'strict' => false. then this solution works well if you try group data when query. Thank you for the answer. – ireshan pathirana Mar 28 '20 at 20:44
  • 1
    You do not want to group by on the web server, you want that group by to be done in SQL. Try your group by approach with a table of 147mil records... – John C Mar 10 '22 at 02:14
  • 1
    Don't do that if you have a big data. Groupping the data outside SQL will kill the performance. – Bulent Jun 20 '22 at 07:56
12

update config/database.php

set:

'mysql' => [
     'strict' => false,
],

instead of:

'mysql' => [
     'strict' => true,
],

and don't forget to clear cache:

php artisan config:cache
Osanda Gamage
  • 446
  • 2
  • 6
  • 16
Gouda Elalfy
  • 6,888
  • 1
  • 26
  • 38
  • beside being replied in 2016 if i can vote you a thousand time i will . banging with it about 24 hours without any clue its being cached. Love you man <3 – Faisal Mehmood Awan Apr 06 '20 at 17:55
12

You can leave 'strict' => true and add modes to "mysql" option in.

'mysql' => [
   ...
   ....
   'strict' => true,
   'modes' => [
        //'ONLY_FULL_GROUP_BY', // Disable this to allow grouping by one column
        'STRICT_TRANS_TABLES',
        'NO_ZERO_IN_DATE',
        'NO_ZERO_DATE',
        'ERROR_FOR_DIVISION_BY_ZERO',
        // 'NO_AUTO_CREATE_USER', // This has been deprecated and will throw an error in mysql v8

        'NO_ENGINE_SUBSTITUTION'
    ],
 ]
Sven Eberth
  • 3,057
  • 12
  • 24
  • 29
8

I was having this problem also but after changing 'strict' => true, to 'strict' => false, the error disappeared.

You can find this setting in:

config\database.php

'mysql' => [
    ...
    'strict' => false,
    ...
]
Chuck Le Butt
  • 47,570
  • 62
  • 203
  • 289
Zakhele
  • 97
  • 1
  • 2
8

Whenever using groupBy in eloquent, always include the column name used in the groupBy function in the select() function.

$loadids=explode("#@*",$reciptdet->loading_id);
$loadingdatas=DB::table('loading')->select('vehicle_no')->groupBy('vehicle_no')->whereIn('id',$loadids)->get();//add select('vehicle_no')

Also it is a bad practice to disable strict mode in the config file. Doing so may cause corrupt data to enter the database such as invalid dates without any warnings.Don't do that unless absolutely necessary.

Thungdemo
  • 136
  • 2
  • 6
5
SQLSTATE[42000]: Syntax error or access violation: 1055  in GROUP BY

If you get the above error, add the following into your database.php file in the config folder:

'mysql' => [
    'strict' => true,
    'modes' => [
        'STRICT_TRANS_TABLES',
        'NO_ZERO_IN_DATE',
        'NO_ZERO_DATE',
        'ERROR_FOR_DIVISION_BY_ZERO',
        'NO_AUTO_CREATE_USER',
        'NO_ENGINE_SUBSTITUTION'
    ],
]
Jakye
  • 6,440
  • 3
  • 19
  • 38
5

Later, after googling for a while, I learnt that the problem was caused by the sql_mode setting, and modified the configuration of config/database.php as strict => false.

Refer to: https://stdworkflow.com/147/laravel-syntax-error-or-access-violation-1055-error

SEYED BABAK ASHRAFI
  • 4,093
  • 4
  • 22
  • 32
drodriguez
  • 150
  • 2
  • 5
3

This restriction makes sense as when you use GROUP BY in MySQL, it returns one row for each value in the columns used in GROUP BY. So, the values of other columns in the selected rows do not make sense to use anywhere. So, it's always recommended to use the best practice and I would recommend not to disable MySQL Strict Mode.

Often developers may need rows of a query grouped by the value of a column. Here they don't need only one row per the unique values of the columns. But they need multiple rows grouped by the unique values of a particular column. For some reason, they use groupBy Query Builder method of Laravel which generates a MySQL GROUP BY query and the developers encounter the above error.

The solution to their problem is to use groupBy Collection method instead. For example,

$loadingData = DB::table('loading')
    ->whereIn('id', $loadIds)
    ->get()
    ->groupBy('vehicle_no');

This will give them the desired result.

Debiprasad
  • 5,895
  • 16
  • 67
  • 95
  • 1
    You do not want to group by on the web server, you want that group by to be done in SQL. Try your group by approach with a table of 147mil records... – John C Mar 10 '22 at 02:12
  • @JohnC In that case, they need to write the queries differently. – Debiprasad Mar 10 '22 at 10:00
  • the only thing you are missing from it being a valid SQL group by, is a valid select. That's all the issue is in all of these... – John C Mar 10 '22 at 19:24
  • @JohnC Yes, of course. You can do that. My answer only addresses the error in the question. – Debiprasad Apr 13 '22 at 12:17
  • Actually it doesn't, the answer is to simply add the correct select statement, and not group by after you made the query. – John C Apr 13 '22 at 14:02
  • @JohnC What if you need to select more columns than the group by columns? – Debiprasad Nov 12 '22 at 06:44
  • That would break the query, as the SQL-92 standard does not allow selecting anything but grouped and aggregated columns in the select clause when using group by. If you are using MySQL, you can use GROUP_CONCAT or ANY_VALUE to work around that limitation. – John C Dec 02 '22 at 20:13
3

You might as well use:

distinct('vehicle_no')

instead of groupBy('vehicle_no') each case scenario is different, but looking at your query, distinct might be the way to go since you're not aggregating data.

ben.c
  • 31
  • 1
2

This is on laravel doc 8.x , it works well

 $users = DB::table('users')
             ->select(DB::raw('count(*) as user_count, status'))
             ->where('status', '<>', 1)
             ->groupBy('status')
             ->get();
Rachid Loukili
  • 623
  • 6
  • 15
-1

add \Schema::defaultStringLength(191); to boot method

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
         \Schema::defaultStringLength(191);
    }
}
hamed hossani
  • 986
  • 2
  • 14
  • 33
-1

I solve a similar issue with using group by by first getting the columns i needed to sort then use the group by.

$SampleData= DB::table('tableExampleName')->get(['col1','col2'])->groupBy('col3');

then you can dd() the values and check if they are the right grouping. You can all assign it and pass it into your view for further testing.

Note: This is using Laravel 8.

ZackAttack
  • 126
  • 12
  • You do not want to group by on the web server, you want that group by to be done in SQL. Try your group by approach with a table of 147mil records... – John C Mar 10 '22 at 02:13