(Laravel) can't use group by with order by [duplicate] - php

This question already has answers here:
Group by not working - Laravel
(8 answers)
Closed 3 years ago.
I'm trying to use order by without adding the order column in groupby, it only works if I execute it directly from the database but from laravel I get database error
I made this eloquent code
Comment::select('product_id')->where('shop_name', $shop)->groupby('product_id')->distinct()->orderBy('created_at')->paginate(12)
it will product the following query
select distinct DISTINCT(product_id) from comments where shop_name
= 'shopname' group by product_id order by created_at asc limit 12 offset 0
if I rub the above query directly in database it works
but if I use Laravel eloquent code it fires this error
SQLSTATE[42000]: Syntax error or access violation: 1055
'areviews_areviewzappz.comments.created_at' isn't in GROUP BY (SQL:
select distinct DISTINCT(product_id) from comments where shop_name
= 'shopname' group by product_id order by created_at asc limit 12 offset 0)
how can I solve this issue ?

The issues is that you SHOULD really include the ORDER BY in the GROUP BY list as this is best practise.
The reason it works when you are on the the sql mode set to ''. However, Laravel by default (I think) has Strict as TRUE,
You have 2 options:
Add the created_at to the GROUP BY clause (Recommended)
Change the strict mode to false
A bit more info on the 2nd option:
How can I solve incompatible with sql_mode=only_full_group_by in laravel eloquent?

You can group it after you have retrieved the results rather than in the MySQL query - so you group the collection after it has been retrieved, not the table entries in the query itself.
Comment::select('product_id')
->where('shop_name', $shop)
->distinct()
->orderBy('created_at')
->paginate(12)
->groupBy('product_id')
Laravel collection groupBy method: https://laravel.com/docs/5.7/collections#method-groupby
Related post: Laravel Query Buider Group By Not Getting All The Records

Related

I have a MySQL query that is working in perfectly in Laravel but when I switch our DB to PostgreSQL it stops working and gives an error

I have a Laravel query that works when our DB is using our MySQL DB, but when I switch to our new PostgreSQL DB it stops working.
I am using Laravel's group by function as below:
$this->crud->groupBy('leads.id')
The whole query translated to mysql is below:
select count(*) as aggregate
from (select leads.* from leads
where leads.club_id in ('TR71') and
leads.deleted_at is null GROUP BY leads.id) as aggregate_table;
The error that is now giving is the following:
"SQLSTATE[42803]: Grouping error: 7 ERROR: column \"leads.name\" must appear in the GROUP BY clause or be used in an aggregate function (SQL: select count(*) as aggregate from (select \"leads\".* from \"leads\" where \"leads\".\"club_id\" in (TR71) and \"leads\".\"deleted_at\" is null group by \"leads\".\"id\") as \"aggregate_table\")"
It pretty much is asking me to list each column from the leads.* part of the query into the group by clause. So far I have tried listing each column but it is not efficient or good practice as we could always end up in the situation where we add more columns to the table
MySQL have an inconsisten behaviour with aggregate calculus.
The SQL standard require that all columns that are in the SELECT clause of a SELECT statement and are not involved in an aggregate function must be specified in the GROUP BY clause. This is probably the case of your subquery that limits the GROUP BY to only the leads.id column.
Excepts MySQL in which it is clearly a bug and returns false data, there is no other RDBMS that accepts such an inconsistent query syntax.... In this case, MySQL returns randomized data that you believe to be thruth !

How can I convert this SQL query to Laravel Eloquent?

One of our teams asked this question earlier today, and there aren't any right answers still. Perhaps the way he worded the question wasn't correct—all in all, this is the SQL query I want to convert to Laravel Eloquent:
SELECT * FROM drivers
where driver_number
NOT IN (SELECT driver_number FROM buses)
AND station_id = 2 OR driver_number = 'Dr_02'
Try this:
Driver::whereNotIn('driver_number', Buse::select('driver_number'))
->where('station_id', 2)
->orWhere('driver_number', 'Dr_02');
If the Buse select gives you an error, add the get method at the end of it:
Buse::select('driver_number')->get()

Laravel Pagination group by year and month only [duplicate]

This question already has answers here:
Laravel pagination not working with group by clause
(5 answers)
Closed 3 years ago.
I want to make paginate from laravel, group by year and month only
when i used get , it work well
$data = DB::table('gallery')
->select(DB::raw('DATE_FORMAT(created_at, "%Y-%m") as tanggal,count(created_at) as jumlah'),'gallery.*')
->where('type','Foto')
->groupBy('tanggal')
->orderBy('tanggal','desc')
->get();
but when i use paginate , there is an error :
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'tanggal' in 'group statement' (SQL: select count(*) as aggregate from gallery where type = Foto group by tanggal)
$data = DB::table('gallery')
->select(DB::raw('DATE_FORMAT(created_at, "%Y-%m") as tanggal,count(created_at) as jumlah'),'gallery.*')
->where('type','Foto')
->groupBy('tanggal')
->orderBy('tanggal','desc')
->paginate(2);
Or any idea for group by just year and month laravel 5.4?
From https://laravel.com/docs/5.4/pagination
Currently, pagination operations that use a groupBy statement cannot be executed efficiently by Laravel. If you need to use a groupBy with a paginated result set, it is recommended that you query the database and create a paginator manually.
Here's an alternative solution provided on Jen's Segers's blog

Laravel groupBy violation [duplicate]

This question already has answers here:
Error related to only_full_group_by when executing a query in MySql
(18 answers)
Closed 4 years ago.
I want to get all messages for auth user in his inbox with name of people who send him messages.
I have query
$user_id=Auth::id();
$messages=Chat::with('user')
->where('user_id',$user_id)
->groupBy('friend_id')
->limit(10)
->get();
But Laravel won't me to get that and said:
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mojaodeca.chats.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 chats where user_id = 1 group by friend_id limit 10)
use this
$user_id=Auth::id();
$messages=Chat::with('user',function($q){
$q->groupBy('friend_id')
})
->where('user_id',$user_id)
->limit(10)
->get();
Please check MySQL Handling of GROUP BY - Your select list must be in your aggregate functions.
$messages = Chat::select('user_id', DB::raw('COUNT(user_id) as count'))
->with('user')
->groupBy('friend_id')
->limit(10)
->get();

Select all columns but distinct from database table in Laravel

Bellow SQL command runs perfectly :
select * from `product` group by `owner_name` order by `id` asc
When I translate above code in my Laravel project to get the same result :
Product::select('*')
->orderBy('id','asc')->groupBy('owner_name')
->get();
This laravel code returns me error that
SQLSTATE[42000]: Syntax error or access violation: 1055
'db1.product.id' isn't in GROUP BY (SQL: select * from product group
by owner_name order by id asc)
Problem is I have many duplicated records with slight differences on some of their columns. I need to get them by owner_name and only one time .
Edit your applications's database config file config/database.php
In mysql array, set strict => false to disable MySQL's strict mode
You have don't need to do 'select(*)', by default it will select all columns data.
Try this:
Product::orderBy('id','asc')->groupBy('owner_name')
->get();
And if you want to fetch selected column you can do like this:
Product::select(['column_1', 'column_2'])
->orderBy('id','asc')->groupBy('owner_name')
->get();

Categories