How to get last month record from databse in laravel? - laravel

i have a table remaining_bus_fees.
id | date | student_id | remaining_balance
-----------------------------------------------------
1 | 2019-04-05 | 1 | 500
2 | 2019-05-10 | 2 | 400
3 | 2019-05-13 | 3 | 300
Now i need how to get last month record against student_id. here is
query i am using. but this is not working for me.
$remain_fee = \DB::table('remaining_bus_fees')
->whereMonth('date', '<', Carbon::now()->subMonth()->month)
->where('student_id', '=', 2)->get();

Here is useful queries :
$today=DB::table('remaining_bus_fees')->whereRaw('Date(created_at) = CURDATE()')->where('student_id', 2)->get();
$yesterday= DB::table('remaining_bus_fees')->whereDate('created_at',Carbon::yesterday())->get();
$last_7_days= DB::table('remaining_bus_fees')->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])->get();
$this_month=DB::table('remaining_bus_fees')->whereMonth('created_at',Carbon::now()->month)->whereYear('created_at', date('Y'))->where('student_id', 2)->get();
$last_month=DB::table('remaining_bus_fees')->whereMonth('created_at',Carbon::now()->subMonth()->format('m'))->whereYear('created_at', date('Y'))->where('student_id', 2)->get();

Change your code to this and it should work fine, you need to convert your Carbon::now() to date format as you will use whereDate here, it will consider only date.
$remain_fee = \DB::table('remaining_bus_fees')
->whereDate('date', '<', Carbon::now()->subMonth()->toDateString())
->where('student_id', '=', 2)->get();
Example in tinker
>>> App\User::whereDate('created_at', Carbon\Carbon::now()->subMonth()->toDateSt
ring())->get()
=> Illuminate\Database\Eloquent\Collection {#3120
all: [
App\User {#3114
id: 90,
name: "******",
email: "******#gmail.com",
created_at: "2019-05-01 06:17:47",
updated_at: "2019-05-02 00:28:18",
},
],
}
>>>

Try this out,
$remain_fee = \DB::table('remaining_bus_fees')
->whereMonth('date', '=', Carbon::now()->subMonth()->month)
->whereStudentId(2)->get();

At the minute your code is saying where date is "before a month ago" whereas it should be where the date is a month ago (i.e. remove <). Also, I would suggest adding the year to the query as well otherwise you'll start to get previous years results.
This should get you what you need:
$date = Carbon::now()->subMonth();
$remain_fee = \DB::table('remaining_bus_fees')
->whereMonth('date', $date->month)
->whereYear('date', $date->year)
->where('student_id', 2)
->get();

Related

How to get missing dates between 7 latest rows from database?

I want to get 7 latest rows (in order from down to up), for the current week (Sunday to Saturday), for the current logged in user.
To do this, I used this one method:
Carbon::setWeekStartsAt(Carbon::SUNDAY);
Carbon::setWeekEndsAt(Carbon::SATURDAY);
$strikes = UserStrike::where('user_id', $user)->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])->latest()->take(7)->get();
$strikes = $strikes->reverse(); //to order the list from DESC to ASC
But the problem with this method is that it doesn't get any missing days.
So if there are data like this for the current week (2020-05-12 is missing):
created_at: 2020-05-10
created_at: 2020-05-11
created_at: 2020-05-13
Then for that one day which is missing, there should be a null in array. Something like this:
$days = ["Sun", "Mon", null, "Wed"];
I'm having hard time to find a way to replace missing day with a null in array.
If anyone here can help me with this problem please leave your comment. Thank you in advance.
You can take data from DB and then create array by iterating on DateTimeInterval(). I don't know Laravel and Carbon well but it could be something like this:
Carbon::setWeekStartsAt(Carbon::SUNDAY);
Carbon::setWeekEndsAt(Carbon::SATURDAY);
$start = Carbon::now()->startOfWeek();
$end = Carbon::now()->endOfWeek();
$strikes = UserStrike::where('user_id', $user)
->whereBetween(
'created_at',
[$start, $end]
)
->latest()
->take(7)
->get();
$strikes = $strikes->reverse();
$timePeriod = new DatePeriod(
$start,
new DateInterval('P1D'),
$end
);
$days = [];
for ($i = 0; $i < count($timePeriod) $i++) {
$days[$i] = null;
foreach ($strikes as $strike) {
if ($strike->created_at->format('Y-m-d') == $timePeriod[$i]->format('Y-m-d') {
$days[$i] = $strike->created_at->format('Y-m-d');
break;
}
}
}

One hour interval - Laravel

I'm trying to select all records based on date/time.
I have this timestamps in postgreSQL:
13/12/2020 11:00:00
14/12/2020 11:31:00
14/12/2020 12:30:00
14/12/2020 13:00:00
15/12/2020 02:00:00
I have a code in the controller getting all records:
$start_date = date('d/m/Y 00:00:00');
$end_date = date('d/m/Y 23:59:59');
if($request->start_date != '' && $request->end_date != '')
{
// if user fill dates
$dateScope = array($request->start_date, $request->end_date);
} else {
// default load page - today
$dateScope = array($start_date, $end_date);
};
$results = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('table1.recordtime','table2.info')
->orderBy('recordtime', 'ASC')
->get();
The goal is to select only records in every hour like this:
13/12/2020 11:00:00
14/12/2020 13:00:00
15/12/2020 02:00:00
I get error when use:
$results = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('extract(hour from table1.recordtime)','table2.info')
->orderBy('recordtime', 'ASC')
->get();
The error is:
Undefined index: recordtime
You could use LIKE to get the records with timestamps that have no minutes or seconds and if there's no other processing required.
$results = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->where('table1.recordtime','LIKE', '%:00:00%')
->selectRaw('table1.recordtime','table2.info')
->orderBy('recordtime', 'ASC')
->get();
Also, your query could probably work with this slight fix (AS column_name)
$results = Tablemodel1::whereBetween('table1.recordtime', $dateScope)
->selectRaw('extract(hour from table1.recordtime) AS recordtime','table2.info')
->orderBy('recordtime', 'ASC')
->get();
Please try something like this:
$result = Tablemodel1::select([
DB::raw('count(table2.info) as counted_info'),
DB::raw('DATE_FORMAT(table1.recordtime, "%H") hour'),
])
->whereBetween('table1.recordtime', $dateScope)
->groupBy('hour')
->orderBy('hour')
->get();
You should do the next steps:
Format date
Group by formatted date (Example: DATE_FORMAT(orders.created_at, "%b %d") day)
Sort (optional)
collect data
All possible formates described here:
enter link description here

Condition in with and whereHas laravel has been duplicate

I have two table
1. news_categories
+----+---------------------+
| id | created_at |
+----+---------------------+
| 1 | 2020-10-10 10:10:10 |
+----+---------------------+
2. news_category_translations
+----+--------+---------------+---------+
| id | map_id | language_code | name |
+----+--------+---------------+---------+
| 1 | 1 | vi | name vi |
| 2 | 1 | en | name en |
+----+--------+---------------+---------+
How do I fix the looping condition in this code
$locale = \App::getLocale()
$category = \App\Models\NewsCategory::with(['translation' => function($q){
$q->where('language_code', 'en'); // duplicate (1)
}])->whereHas('translation', function($q){
$q->where('language_code', 'en'); // duplicate (2)
})->find(1);
Model NewCategory
public function translation()
{
return $this->hasOne('App\Models\NewsCategoryTranslation', 'map_id', 'id');
}
I don't want to push conditional on the model.
Update 1:
When i remove condition (1) output:
newsCategory ['id' => 1, 'translation' => ['id' => 1]] false because language_code = en
When i remove condition (2) and delete translation with id = 2 ouput:
newsCategory ['id' => 1, 'translation' => null] => false because record with language_code = en does not exist
When I use both conditions, the result is as expected. Why?
Sorry my english is quite bad and i don't have much experience with laravel. Thanks.
Update 2:
I have referenced the following article
https://medium.com/#amritms/combining-wherehas-and-with-in-laravel-eloquent-c91391bd3c02
And i see author use
$callback = function($query) {
$query->where('something', '=', 'something');
}
$submissions = Post::whereHas('submissions', $callback)->with(['submissions' => $callback])->get();
If don't use it callback function it will be the same for me, duplicate condition from with and whereHas.

Is it possible to groupBy (month) and sum (each column) in table

+---------+--------+---------+---------+
| date | type_a | type_b | type_zzz|
+---------+--------+---------+---------+
|01-01-18 | 12 | 10 | 1 |
|02-01-18 | 2 | 5 | 1 |
|03-01-18 | 7 | 2 | 2 |
|01-02-18 | 13 | 6 | 55 |
|02-02-18 | 22 | 33 | 5 |
+---------+--------+---------+---------+
Hi,
In above example, I would like to know if it's possible to groupBy month and sum each column when getting results in Laravel (tables are dynamic so there are no models for them and also some tables don't have column 'type_a' other don't have 'type_zzz' etc...).
What I'm looking to get from above table is something like this:
"01" =>
'type_a' : '21',
'type_b' : '17',
'type_zzz': '4'
"02" =>
'type_a' : '35',
'type_b' : '39',
'type_zzz': '60'
I'm using following code to group it by month but I'm not able to find solution to return sum by each column:
DB::table($id)->get()->groupBy(function($date) {
return Carbon::parse($date->repdate)->format('m');;
});
If I understand your question correctly, you can either group and sum the values using an SQL query:
$grouped = DB::table('table_name')
->selectRaw('
SUM(type_a) AS type_a,
SUM(type_b) AS type_b,
SUM(type_z) AS type_z
')
->groupByRaw('MONTH(date)')
->get();
Or if you don't want to have to specify the column names in each query, you can use groupBy, array_column, and array_sum on your collection:
$grouped = DB::table('table_name')
->get()
->groupBy(function ($item) {
return Carbon::parse($item->date)->format('m');
})
->map(function ($group) {
$group = $group->toArray();
$summed = [];
$columns = array_keys($group[0]);
array_shift($columns);
foreach ($columns as $column) {
$summed[$column] = array_sum(array_column($group, $column));
}
return $summed;
});

Count from each distinct date, fill in missing dates with zero

I'm trying to create an Eloquent query that gets the total number of posts made each distinct day, and if the date is missing, fill it in with a value of zero.
For example, if my table looks like this:
+----+---------------------+
| id | date |
+----+---------------------+
| 1 | 2015-01-01 00:00:00 |
| 2 | 2015-01-01 01:53:18 |
| 3 | 2015-01-01 02:41:26 |
| 4 | 2015-01-02 12:51:01 |
| 5 | 2015-01-05 08:24:12 |
+----+---------------------+
This would output:
2015-01-01 : 3
2015-01-02 : 1
2015-01-05 : 1
Notice, however, that the days 03-04 are missing. How can I include these dates, but give them the value 0 such that I end up with an output like:
2015-01-01 : 3
2015-01-02 : 1
2015-01-03 : 0
2015-01-04 : 0
2015-01-05 : 1
Here is my current query:
$posts = Post::select(array(
DB::raw('DATE(`created_at`) as `date`'),
DB::raw('COUNT(*)as `count`')
))
->where('created_at', '>', Carbon::today()->subWeek())
->groupBy('date')
->orderBy('date', 'DESC')
->lists('count', 'date');
Thanks!
In your SQL results you can generate some "fake-data" in your rows, but u can not generate "fake-rows", exept joining to some "fake(temporary)-table".
In your case ll be much easier to apply some logic around sql-result.
Replace your code with this:
$order = 'DESC';
$endDate = Carbon::today();
$startDate = Carbon::today()->subWeek();
$dateInc = ($order == 'DESC') ? -1 : 1;
$dateCycleHolder = clone ($dateInc > 0 ? $startDate : $endDate);
$dateCycleEnd = clone ($dateInc > 0 ? $endDate : $startDate);
$posts = Post::select(array(
DB::raw('DATE(`created_at`) as `date`'),
DB::raw('COUNT(*)as `count`')
))
->where('created_at', '>', $startDate)
->groupBy('date')
->orderBy('date', $order)
->lists('count', 'date');
$postsFinal = new \Illuminate\Database\Eloquent\Collection();
while ($dateCycleHolder->ne($dateCycleEnd)) {
$dateCurr = $dateCycleHolder->format('Y-m-d');
$postsFinal->put($dateCurr, $posts->get($dateCurr, 0));
$dateCycleHolder->addDay($dateInc);
}
$dateCurr = $dateCycleHolder->format('Y-m-d');
$postsFinal->put($dateCurr, $posts->get($dateCurr, 0));
$posts = $postsFinal;
its alittle bit flexible, you can change values of this things:
$order = 'DESC';
$endDate = Carbon::today();
$startDate = Carbon::today()->subWeek();

Resources