GroupBy just doesn't work on collection in Laravel 5.6, it is very annoying when simple things which supposed to work not wirking...
$users = Game::orderBy('game_count', 'desc')->get();
$users_grouped = $users->groupBy('user_id');
As you might guess $users_grouped contains the same collection as $users with the same repeating user_id values.
I don't get why it doesn't work as expected and how to fix it?
At least GROUP BY works with raw DB select hopefully.. But I want to use Eloquent..
You're confusing eloquent's query builder with collections. They are not the same thing.
groupBy on a query builder instance will use an SQL GROUP BY and give one aggregated result for the column(s) you are grouping on.
groupBy on a collection instance will return a new collection that groups all collected items by the given key's value.
https://laravel.com/docs/5.6/collections#method-groupby
If you want to use the query builder's groupBy method, chain it before the get():
$users = Game::orderBy('game_count', 'desc')->groupBy('user_id')->get();
get() executes the query and returns the collection of records.
If you want to group the query by user_id just do the groupBy before the get(), as the following row:
$users = Game::orderBy('game_count', 'desc')->groupBy('user_id')->get();
The rows will be the same. You should make two querys:
$users = Game::orderBy('game_count', 'desc')->get();
$users_grouped = Game::orderBy('game_count', 'desc')->groupBy('user_id')->get();
Temporary solution for this is the raw SQL query:
$users_grouped = DB::select('SELECT COUNT(id) AS theCount, `user_id` from `quiz_games` GROUP BY `user_id` ORDER BY theCount DESC');
Related
Is it possible in Laravel, using eloquent to get the raw SQL query generated by the ORM query ?
Also, is it possible to get an array of all the columns involved in that query ?
Consider for exemple that Eloquent query:
$query = Category::join('posts', 'post.category_id', '=', 'category.id');
Would it be possible to retrieve in the code, the raw SQL of that query, and most importantly, an array of the columns involved ? In this cas, the columns of the Category and the Post models (category.id, category.name, post.id, post.title, post.category_id, etc...)
You can enable ORM logging with:
DB::enableQueryLog();
// query
and when your query executed you can get it with:
DB::getQueryLog();
You can use toSql() and getBindings() and for query builder same as:
$sql = $query->toSql();
$bindings = $query->getBindings();
If you do not provide any fields it will default to *
I am trying to get the data using groupBy on type field from my transaction table. I am using this query
DB::table($this->table)
->select()
->whereRaw($where['rawQuery'], isset($where['bindParams']) ? $where['bindParams'] : array())
->groupBy('type')
->get();
But it is not giving the complete records. There are more than 10 records in my table. But it is giving me only two. One for type=1 and another for type=2. It is selecting only on record from each type. I am expecting that i will get all the transactions based on condition grouped in two result set. Anyone know why it is happening?
Try to call Collection groupBy instead. Just put groupBy after get(). It should work.
DB::table($this->table)
->select()
->whereRaw($where['rawQuery'], isset($where['bindParams']) ? $where['bindParams'] : array())
->get()
->groupBy('type');
Faq::where('type','host')->get()->groupBy('category');
I got this query written out in Laravel query builder, bu when i run it, it returns this error: Call to a member function join() on float
$avgYield= DairyCropYield::avg('moisture')
->join('dairy_crops','dairy_crops.id','=','dairy_crop_yields.dairy_crop_id')
->join('dairy_crop_varieties','dairy_crops.dairy_crop_variety_id','=','dairy_crop_varieties.id')
->where('dairy_crop_varieties.crop','=',$crop->crop)
->whereYear('harvested_at','=',Carbon::now()->year)
->get();
But when i write the same query in mySql it wroks as exptected:
SELECT AVG(moisture) FROM dairy_crop_yields AS yield JOIN dairy_crops AS crop ON crop.id = yield.dairy_crop_id JOIN dairy_crop_varieties AS variety ON variety.id = crop.dairy_crop_variety_id WHERE variety.crop = 'corn' AND YEAR(harvested_at) = 2015
Any thoughts / suggestions on what I am not doing right in Laravel query builder.
I do want to master and stick with Laravel's query builder.
Thanks.
Put the avg after the get(), the avg method works on a collection. So what you want is to get() all the result first then only call the avg('moisture') on the available results.
$avgYield= DairyCropYield::join('dairy_crops','dairy_crops.id','=','dairy_crop_yields.dairy_crop_id')
->join('dairy_crop_varieties','dairy_crops.dairy_crop_variety_id','=','dairy_crop_varieties.id')
->where('dairy_crop_varieties.crop','=',$crop->crop)
->whereYear('harvested_at','=',Carbon::now()->year)
->get()
->avg('moisture');
Alternately, you can also do something like this using DB::raw
$avgYield= DairyCropYield::select(DB::raw('AVG(moisture)'))
->join('dairy_crops','dairy_crops.id','=','dairy_crop_yields.dairy_crop_id')
->join('dairy_crop_varieties','dairy_crops.dairy_crop_variety_id','=','dairy_crop_varieties.id')
->where('dairy_crop_varieties.crop','=',$crop->crop)
->whereYear('harvested_at','=',Carbon::now()->year)
->get();
I want to groupBy() task using Laravel Eloquent. I have searched Internet and didn't find anything with eloquent.
some people used groupBy() query with Query Builder like this link
But I want to create query like this style:
Task::select('id')->groupBy('category_id')->count();
This code just return only count of first category_id. But I want count of all the category_id.
Native Collection alternative (grouped by php, not mysql). It's a nice option when you have the Collection as variable already assigned. Of course is less optimal than mysql grouping in most cases.
$tasks->groupBy('category_id')->map->count();
You should add the count to the select function and use the get function to execute the query.
Task::select('id', \DB::raw("count(id)"))->groupBy('category_id')->get();
The \DB::raw() function makes sure the string is inserted in the query without Laravel modifying its value.
More simple:
Task::select('id')->groupBy('category_id')**->get()**->count();
You can do something like this:
return DB::table('offers')->select('*', DB::raw('count('.$field.') as total_count'))->groupBy($field)->get();
I overrode the count() method in my model. Could be something like:
public function count($string = '*'){
$tempmodel = new YourModel();
return $tempmodel ->where('id',$this->id)->where('category_id',$this->category_id)->count($string);
}
This gave me exactly the behavior of count() I was looking for.
Worked for me as
we need to select one column like 'category_id' or 'user_id' and then
count the selected column on get()
Task::select('category_id')
->where('user_id',Auth::user()->id)
->groupBy(['category_id'])
->get()
->count();
This works for me.
output:
return $email_trackers = EmailTracker::get()->groupBy('campaign_id')->map->count();
{
"6": 2
}
i am looking to produce the following query in laravel 5.1 with eloquent method.
The mysql query is a follows
SELECT * FROM orders WHERE 1 = 1 ORDER BY o_date DESC LIMIT 25
No matter what i cant get the
WHERE 1 = 1
part working.
am new to laravel and pretty sure this is easy. but can't figure it out.
I have tried the following variations
$orders = orders::where('1', 1)->orderBy('o_date', 'desc')->take(25)->get();
$orders = orders::where(1)->orderBy('o_date', 'desc')->take(25)->get();
$orders = orders::where('1', '=', '1')->orderBy('o_date', 'desc')->take(25)->get();
but its not working. the query results is as shown below
> select count(*) as aggregate from `orders`
Seems like (looking at 1=1) you need whereRaw
$orders = orders::whereRaw("any clause u wish")->orderBy('o_date', 'desc')->take(25)->get();
but if "any clause u wish" is not a VERY-VERY dinamical part u'd better look what else you can use
http://laravel.com/api/5.0/Illuminate/Database/Query/Builder.html
For the above example the below code works fine
$orders = orders::whereRaw("1 = 1")->orderBy('o_date', 'desc')->take(25)->get();
Why do you want to create a condition that will be always true? I think that Eloquent is smart enought to remove this useless part of the query.