Laravel groupBy inside with doesnt work properly - laravel

Hello guys after searching in the web and laravel docs and similar questions in Stackoverflow(without answers) I finally come here for help
The following query gives me this result
https://drive.google.com/file/d/187XhxyfUUjcIo6y3LufbDIF7T4gZ2LnB/view?usp=sharing
$lotes_query=Lote::with(['salidas' => function ($q) {
$q->select(DB::raw('*,sum(cantidad) as cantidad_total, 0 as precio_total'))->groupBy('inventario_entrada_id')->with('entrada');
}])->whereIn("cod_lote",['1722H','1722H','1822M'])->get();
Just 1 of the json objects have the relantionship salidas and the rest ones show the salidas array empty
However if I change the Query to
$lotes_query=Lote::with(['salidas' => function ($q) {
$q->with('entrada');
}])->whereIn("cod_lote",['1722H','1722H','1822M'])->get();
The results would be
https://drive.google.com/file/d/1CrAVvP9BquG69WMurJVpsXZnw2uqkIl_/view?usp=sharing
On that second query relantionship now exist on all the Lotes however it returns a lot of results for salidas I only need to group by , sum the quantity column (cantidad) to know how much I have spent for each type of food in all my lotes
Any type of help would be highly appreciated it thank you

Related

laravel unique() dont work with paginating

i'm facing with an issue in laravel 5.7.28, i'm trying to get records with all of my fields and paginate them , sadly i got a bug in my code that cause registering users with duplicate phone number(a user registered itself more than one time and of course i fix the bug ) , for now i'm facing with a scenario that i want to fetch my (non-duplicate) distinct users on their phone, and paginate them . here is wishful scenario :
$users = User::distinct('phone')
->doesntHave('carrierUsers')
->doesntHave('thirdparty')
->latest()->paginate(40);
it returns all users (with duplicate phone number), seems distinct function not affected , so i tried unique function :
$users = User::doesntHave('carrierUsers')
->doesntHave('thirdparty')
->latest()->paginate(40)->unique('phone');
it works (for getting non-duplicate) but break paginating functionality
and for
$users = User::doesntHave('carrierUsers')
->doesntHave('thirdparty')
->latest()
->unique('phone')
->paginate(40);
i got error for undefined function on builder , means it works on collections ,
also i tried groupBy (search whole the web for solution) , it makes me confused till when i use it
User::doesntHave('carrierUsers')->doesntHave('thirdparty')
->latest()->groupBy('phone')
->paginate(40);
i got SELECT list is not in GROUP BY clause, is that mean in every phrase in my select statement (for now is all ('*') ) i should use it in my groupBy ?
i mean i need all columns , how can i have all those column in groupBy clause ? whats that mean by the way ?
, error is telling : this is incompatible with sql_mode=only_full_group_by. is she making this happen ? how can i fix it ?
1) excuse me for my english
2) Thanks for reading whole this
3) pleasure to reply and help me
Problem 1: Use distinct
For distinct() method, passing parameters is not supporteds, so distinct(phone) will not works.
You can use ->select('phone')->distinct() instead. However, support unique column is selected.
Problem 2: Use Group By
So if you want to select all columns and unique one column, you can use group by.
And because you are using mysql 5.7+.
The ONLY_FULL_GROUP_BY and STRICT_TRANS_TABLES modes were added in MySQL 5.7.5.
So if you select all columns and group one column, you will get the only_full_group_by error.
There are two options can solve this problem.
Solution1:
Use ANY_VALUE()
User::doesntHave('carrierUsers')->doesntHave('thirdparty')
->latest()
->selectRaw('phone, ANY_VALUE(id) AS id, ANY_VALUE(username) AS username, ...')
->groupBy('phone')
->paginate(40);
Solution2:
In config/database.php configuration, set strict mode to false(This is not very safty):
'mysql' => [
'driver' => 'mysql',
...
'strict' => false,
],

Paginate Many to Many

I have a many to many relationship that looks like so
batches -> batch_contributors -> contributors
I am running into an issue when attempting to paginate, I am doing the following:
$contributions = Batch::with('contributors')->where('id', '=' , $batchid)->paginate(10);
Here are samples from my parsed JSON (faker data)
parsed JSON
end of parsed JSON
My problem is the contributor records are listed under the single batch record, so pagination is seeing this and loading all 100 contributors on the first page instead of 10 per page.
How do I get pagination to look at the contributor level instead of the batch level?
You can just invert the call and get contributors where batchId is equal to the one u parse, something like this:
Contributor::with(['batches' => function($query) use ($batchId) {
$query->where('id', $batchId);
}])->paginate(10);
Try this:
Batch::with('contributors', function($query){
$query->take(10); // to take 10 contributors for all the 10 selected Batchs
})->where('id', '=' , $batchid)->paginate(10);
Laravel will get 10 contributors in this case, and try to map them into the batchs, So If those 10 contributors belong to one batch, the rest batchs won't have any contributors.

Drill down into laravel eloquent relationships

I have a problem that’s broken into 2 parts:
1) I’m trying to get the specific events where rsvps = the logged in user_id.
2) And then filter that where event_date <= today to get the past events.
I’m getting stuck on #1. When I run
$favorites = Event::with('rsvps')->get();
I get all the events that include the rsvps which is good but I can’t filter it based on the rsvps info.
[
{"id":1,"user_id":"1","created_at":"2016-03-01 02:26:48","updated_at":"2016-03-01 02:26:48","event_name":"Awesome Event","event_venue":"The Rainbow Room","address":"612 Rachael Ln.","event_details":"Epic","event_date":"03\/12","image":"2016-03-01-02-26-48-heartHands.jpg","time":"8:00",
"rsvps":[
{"id":1,"created_at":"2016-03-01 02:28:39","updated_at":"2016-03-01 02:28:39","event_id":"1","user_id":"1"}]
},
{"id":2,"user_id":"1","created_at":"2016-03-01 02:40:05","updated_at":"2016-03-01 02:40:05","event_name":"New Event","event_venue":"My House","address":"612 Rachael Ln.","event_details":"Epic","event_date":"03\/01","image":"2016-03-01-02-40-05-img3.jpg","time":"8:00",
"rsvps":[
{"id":2,"created_at":"2016-03-01 02:40:12","updated_at":"2016-03-01 02:40:12","event_id":"2","user_id":"1"},
{"id":3,"created_at":"2016-03-01 22:21:33","updated_at":"2016-03-01 22:21:33","event_id":"2","user_id":"2"}
]}
]
When I run a test to just get the rsvps with the user_id = 1:
$favorites = Event::with('rsvps')->find('id')->where('rsvps->user_id', '1')->get();
it gives me the error: Call to a member function where() on null
Can someone please give me a clue as to what I'm doing wrong?
You need to query the relationship rsvps. You are trying to query the events.
$favorites = Event::whereHas('rsvps', function($q) {
$q->where('user_id', 1)
})->find('id'); // Passing in 'id' won't work here, it should be the actual id of an event.

proper usage of queries (Aggregates) in laravel 4.2

im trying to get the total count of records that are less than a value in my table so im using this query in laravel 4.2
$critical = DB::table('dbo_modules')
->where('ModuleCountLeft','<','ModuleCriticalLevel')
->count();
and passes it like this
return View::make('ssims.board' ,compact('title','mTotal','critical'));
//please don't mind the others
then receives it in the view page like this
<div>Modules at critical level <span><strong><?= $critical ?></strong></span></div>
unfortunately, im getting zero whereas in my database, i have 2 records where ModuleCountLeft is less than ModuleCriticalLevel
any ideas?
thanks
Hi turns out that i needed to pluck out the value of ModuleCriticalLevel first here is the code
$critical = DB::table('dbo_modules')
->where('ModuleCountLeft' , '<' , DB::table('dbo_modules')->pluck('ModuleCriticalLevel') )
->count();
-thumbs up here-

Laravel Eloquent - distinct() and count() not working properly together

So I'm trying to get the number of distinct pids on a query, but the returned value is wrong.
This is what I try to do:
$ad->getcodes()->groupby('pid')->distinct()->count()
what returns the value "2", while the value it should return, should be "1".
As a workaround, I'm doing this:
count($ad->getcodes()->groupby('pid')->distinct()->get())
what works fine and returns "1"
Is there any rule where count and distinct cannot be on the same query? I find the workaround kind of "heavy", I would like to make the original query work :(
The following should work
$ad->getcodes()->distinct()->count('pid');
A more generic answer that would have saved me time, and hopefully others:
Does not work (returns count of all rows):
DB::table('users')
->select('first_name')
->distinct()
->count();
The fix:
DB::table('users')
->distinct()
->count('first_name');
Anyone else come across this post, and not finding the other suggestions to work?
Depending on the specific query, a different approach may be needed. In my case, I needed either count the results of a GROUP BY, e.g.
SELECT COUNT(*) FROM (SELECT * FROM a GROUP BY b)
or use COUNT(DISTINCT b):
SELECT COUNT(DISTINCT b) FROM a
After some puzzling around, I realised there was no built-in Laravel function for either of these. So the simplest solution was to use use DB::raw with the count method.
$count = $builder->count(DB::raw('DISTINCT b'));
Remember, don't use groupBy before calling count. You can apply groupBy later, if you need it for getting rows.
You can use the following way to get the unique data as per your need as follows,
$data = $ad->getcodes()->get()->unique('email');
$count = $data->count();
Hope this will work.
I had a similar problem, and found a way to work around it.
The problem is the way Laravel's query builder handles aggregates. It takes the first result returned and then returns the 'aggregate' value. This is usually fine, but when you combine count with groupBy you're returning a count per grouped item. So the first row's aggregate is just a count of the first group (so something low like 1 or 2 is likely).
So Laravel's count is out, but I combined the Laravel query builder with some raw SQL to get an accurate count of my grouped results.
For your example, I expect the following should work (and let you avoid the get):
$query = $ad->getcodes()->groupby('pid')->distinct();
$count = count(\DB::select($query->toSql(), $query->getBindings()));
If you want to make sure you're not wasting time selecting all the columns, you can avoid that when building your query:
$query = $ad->select(DB::raw(1))->getcodes()->groupby('pid')->distinct();
I came across the same problem.
If you install laravel debug bar you can see the queries and often see the problem
$ad->getcodes()->groupby('pid')->distinct()->count()
change to
$ad->getcodes()->distinct()->select('pid')->count()
You need to set the values to return as distinct. If you don't set the select fields it will return all the columns in the database and all will be unique. So set the query to distinct and only select the columns that make up your 'distinct' value you might want to add more. ->select('pid','date') to get all the unique values for a user in a day
Based on Laravel docs for raw queries I was able to get count for a select field to work with this code in the product model.
public function scopeShowProductCount($query)
{
$query->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))
->groupBy('pid')
->orderBy('count_pid', 'desc');
}
This facade worked to get the same result in the controller:
$products = DB::table('products')->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))->groupBy('pid')->orderBy('count_pid', 'desc')->get();
The resulting dump for both queries was as follows:
#attributes: array:2 [
"pid" => "1271"
"count_pid" => 19
],
#attributes: array:2 [
"pid" => "1273"
"count_pid" => 12
],
#attributes: array:2 [
"pid" => "1275"
"count_pid" => 7
]
$solution = $query->distinct()
->groupBy
(
[
'array',
'of',
'columns',
]
)
->addSelect(
[
'columns',
'from',
'the',
'groupby',
]
)
->get();
Remember the group by is optional,this should work in most cases when you want a count group by to exclude duplicated select values, the addSelect is a querybuilder instance method.
Wouldn't this work?
$ad->getcodes()->distinct()->get(['pid'])->count();
See here for discussion..
Distinct do not take arguments as it adds DISTINCT in your sql query, however, you MAY need to define the column name that you'd want to select distinct with. Thus, if you have
Flight->select('project_id')->distinct()->get() is equialent to SELECT DISTINCT 'project_id' FROM flights and you may now add other modifiers like count() or even raw eloquent queries.
Use something like this
DB::table('user_products')->select('user_id')->distinct()->pluck('user_id')->toArray();
This was working for me so
Try This:
$ad->getcodes()->distinct('pid')->count()
try this
$ad->getcodes()->groupby('pid')->distinct()->count('pid')

Resources