How to get datas by month? Laravel Eloquent - laravel

Using the created_at column, I want to retrieve data(s) in one query:
from past year
group by month
Expected returned values should:
$data: [
1 : [
//datas for january
],
2 : [
//datas for february
],
//etc.
]
I tried this query:
$data = User::query()
->whereYear('created_at', now()->year - 1)
->get(function ($q){
return groupBy(function ($q){
return Carbon::parse($q->created_at)->format('m');
});
});
But I receive this error:
stripos() expects parameter 1 to be string, object given
Can someone could help me the proper querying for this?

The nested closure functions with same variable names are very confusing, you can simplify things here
Call the groupBy method on the collection after get instead of the builder which only accepts a column name apparently
$data = User::query()
->whereYear('created_at', now()->year - 1)
->get()
->groupBy(function ($q) {
return Carbon::parse($q->created_at)->format('m');
});
See Docs

you should use sql method MONTH() to extract month from date then use groubby .like this :
User::query()->select('created_at', DB::raw('MONTH(created_at) month'))
->whereYear('created_at', now()->subYear())
->groupby('month')
->get();

Related

Filter record through dates not working laravel

I have a expiry_date (type=date) column in my table
$currentDate = date('Y-m-d');
$Data = Post::whereDate('expiry_date','<=',$currentDate)->where(['status' => 'active'])->orWhere(['p_id' => 3])->select('id','title','status','p_id','expiry_date')->orderBy('id', 'DESC')->get();
i want to filter data if current date is greater than expiry date then those record should not be shown but in my scenario i'm still getting record.
Any solution Thanks.
You must group orWhere clause in closure. Grouping in closure is like () in real query.
$Data = Post::whereDate('expiry_date','<=',$currentDate)
->where(function($query){
return $query
->where(['status' => 'active'])
->orWhere(['p_id' => 3]);
})
->select('id','title','status','p_id','expiry_date')
->orderBy('id', 'DESC')
->get();
But, because I don't know your project - i may wrong with grouping.

how to write where condition in relation table in Laravel in query

I have 3 table that is Resort, Booking, Expense, these tables are join with relation. the code is given below,
$resorts = Resort::where('status',1)->with('bookings')->withSum('bookings', 'amount')
->with('expenses')->withSum('expenses', 'amount')->get();
I want to sort this table using the date field. how could I use the wherebetween in this query for bookings and expense?
you can pass array in with() like this
$resorts = Resort::where('status', 1)
->with(
['bookings' => function ($q) {
$q->wherebetween('colName', ['startDate','endDate']);
}]
)->withSum('bookings', 'amount')
->with(
['expenses' => function ($q) {
$q->wherebetween('colName', ['startDate','endDate']);
}]
)->withSum('expenses', 'amount')
->get();
ref link https://laravel.com/docs/8.x/eloquent-relationships#constraining-eager-loads

How to group records in year and month? laravel

I have been already to this link but its different in my case.
I have record which has a column created_at. My objective is to group the record by year, and inside each year, records should be group in month also.
My expectations:
I have tried this code below, but it is working only for yearly only.
$records = \App\VehicleRental::query()
->where('operator_id', $operator->id)
->get()
->groupBy(function($val) { return \Carbon\Carbon::parse($val->created_at)->format('Y'); });
So I have tried to put another group for month but error Property [created_at] does not exist on this collection instance. returned
$record = \App\VehicleRental::query()
->where('operator_id', $operator->id)
->get()
->groupBy(function($val) { return \Carbon\Carbon::parse($val->created_at)->format('M'); })
->groupBy(function($val) { return \Carbon\Carbon::parse($val->created_at)->format('Y'); });
Someone knows how to achieve this?
You could also pass an array of elements to the groupBy() collection method, for nested grouping. Try this:
$record = \App\VehicleRental::query()
->where('operator_id', $operator->id)
->get()
->groupBy([
function ($val) { return $val->created_at->format('Y'); },
function ($val) { return $val->created_at->format('m'); },
]);
As a side note, the created_at could be directly casted as a Carbon instance. If the above doesn't work, define the attribute date mutator in your model:
# VehicleRental.php
protected $dates = ['created_at', 'updated_at'];

Laravel whereDate() not working

I have used below query to get result with some codition in my controller
$events = Event::whereHas('topic', function ($q) {
$q->where('delete_status', 0);
})
->where('status', 1)
->where('delete_status', 0);
And in my view file i have used this variable thrice to check with Date like below
$events->where('type', '!=', 2)->whereDate('start_date', '>=', \Carbon\Carbon::now())->get()
And
$events->where('type', 2)->whereDate('start_date', '>=', \Carbon\Carbon::now())->get()
And
$events->whereDate('start_date', '<', \Carbon\Carbon::now())->get()
Because i want to get the result based on past date or present date. If i use get in controller query i got error of whereDate() does not exists
So i have used get() method in view file.
I cannot get record from second and third query but I can only get record from 1st query in view file.
Any solution?
$events is an collection which doesn't have whereDate method, what you might be looking for is the filter() to filter your collection in your views. Hence you could do so
$filtered_events =
$events->where('type', 2)
->filter(function ($item) {
return Carbon::parse($item->start_date)->gte(Carbon::today());
});
Reference

Order by sum column relationship in Laravel

I have this controller which grabs posts from a post table.
Every post in the posts table have the relation "hasMany" with another table likes.
Controller:
public function getDashboard(){
$posts = Post::orderBy('created_at', 'desc')->get();
return view('dashboard', ['posts' => $posts]);
}
I'd like to replace 'created at' with something like:
$post->likes->sum(like)
Don't know how to write the right syntax though.
EDIT:
Here are the tables.
Posts
--id
--body
Likes
--id
--post_id
--like
The column like can have the value 1 or -1.
I'd like to order on the summation of that column for each post.
So a post with one dislike(-1) and one like(1) will have the aggregated value of 0, hence will be placed after a post with one like(1).
You can use withCount() for this as:
Post::withCount('likes')->orderBy('likes_count')->get()
withCount() will place a {relation}_count column on your resulting
models
Update
Post::withCount(['likes' => function($q) {
$q->where('like', 1)
}])
->orderBy('likes_count')
->get()
Update2
You can use sortByDesc() to sort your collection as:
$posts = Post::get();
$posts = $posts->sortByDesc(function ($post) {
return $post->likes->sum('like');
});
If you want to sum column value from relationship and then sort records.
$users = User::addSelect(['likes' => Post::selectRaw('sum(likes) as total_likes')
->whereColumn('user_id', 'useres.id')
->groupBy('user_id')
])
->orderBy('likes', 'DESC')
->get()
->toArray();
Or
use below
$users = User::select("*",
\DB::raw('(SELECT SUM(likes) FROM likes_table WHERE likes_table.user_id = users.id) as tolal_likes'))
->orderBy('likes', 'DESC')
->get()
->toArray();

Resources