One hour interval - Laravel - 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

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;
}
}
}

How to Only fetch time from timestamp in laravel

I am working on a Laravel project. I am trying to fetch time from a timestamp. This is the code I'm using to try to accomplish this:
$details=DB::table('CourseListNew as cl')
->select(
'cl.Title',
'p.Title as ParentTitle',
'cd.Trainer',
DB::raw('day(cd.StartingDate) as day'),
DB::raw('day(cd.EndingDate) as day_end'),
DB::raw('(cd.StartingDate) as month'),
DB::raw('year(cd.StartingDate) as year'),
DB::raw('time(cd.StartingDate) as start_time'),
DB::raw('time(cd.EndingDate) as end_time'),
'cd.StartingDate',
'cd.EndingDate',
'cd.Duration',
'cd.Type',
'cd.Fee',
'cd.Venue',
'count (s.Id) as TotalRegistartion'
)
->join('CourseListNew as p','p.Id', '=', 'cl.ParentId','left')
->join('CourseDetailsNew as cd','cd.CourseId', '=', 'cl.Id')
->join('Student as s','s.CourseId', '=', 'cl.Id', 'left outer')
->orderBy('cl.Id','DESC')
->get();
i want to get time in 12 hours format with AM/PM but not able to find any working solution. i am not using eloquent.
Assuming you are using MySQL, you can replace the TIME function with DATE_FORMAT
$details=DB::table('CourseListNew as cl')
->select(
'cl.Title',
'p.Title as ParentTitle',
'cd.Trainer',
DB::raw('day(cd.StartingDate) as day'),
DB::raw('day(cd.EndingDate) as day_end'),
DB::raw('(cd.StartingDate) as month'),
DB::raw('year(cd.StartingDate) as year'),
DB::raw('DATE_FORMAT(cd.StartingDate, '%r') as start_time'),
DB::raw('DATE_FORMAT(cd.EndingDate, '%r') as end_time'),
'cd.StartingDate',
'cd.EndingDate',
'cd.Duration',
'cd.Type',
'cd.Fee',
'cd.Venue',
'count (s.Id) as TotalRegistartion'
)
->join('CourseListNew as p','p.Id', '=', 'cl.ParentId','left')
->join('CourseDetailsNew as cd','cd.CourseId', '=', 'cl.Id')
->join('Student as s','s.CourseId', '=', 'cl.Id', 'left outer')
->orderBy('cl.Id','DESC')
->get();
The %r format corresponds to the 12-hour time followed by AM or PM.
For more details read the documentation on: DATE_FORMAT
In SQL Server the equivalent method would be FORMAT(time, N'hh:mm tt') and you might need to refer to your own DBMS documentation for the equivalent in other flavours of SQL
For a Laravel generic solution you can of course just format the date after you've gotten the data using Carbon
use Mysql DATE_FORMAT
DB::raw('DATE_FORMAT(cd.EndingDate,'%Y-%m-%d %h:%i %p') as end_time')

How to get last month record from databse in 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();

How to fetch users who does not have reports for 6 consecutive months using laravel?

I'm developing a report system, and I want to fetch users who did not report for six (6) consecutive months. How do I achieve this?
I've tried the code below but I'm not getting the desired output. There is also a problem. Let's say the date interval is 12 months. How can I determine if there is no report for 6 consecutive months?
$dateStart = '2018-10-31';
$dateEnd = '2019-03-31';
$intervals = Carbon::parse($dateStart)->diffInMonths($dateEnd);
$users = $users->whereDoesntHave('reports', function($query) use($intervals) {
for ($i = 5; $i >= 0; $i--) {
$firstMonth = Carbon::parse($dateEnd)->subMonthsNoOverflow($intervals);
$query->where('date', '>=', $firstMonth->format('Y-m-d'))->where('date', '<=', $dateEnd);
}
});
What I will do is that I will create a loop per month based on the start and end date, then check if he did not have a report for that month. If it doesn't have a report for that month, I will increment a counter, and if that counter reaches 6 counts, exit the loop and the condition was satisfied.
Below is the basic idea:
$dateStart = '2018-10-31';
$dateEnd = '2019-10-31';
$count = 0;
$no_report_for_6_consecutive_months = 0 ;
startloop
$have_report = Model::whereMonth('date_column', $date_of_loop->format('m'))->get();
if($have_report->count()){
$count = 0;
}
else{
$count++;
}
if($count==6){
$no_report_for_6_consecutive_months = 1 ;
break;
}
endloop
You have to find distinct users who report for six (6) consecutive and get difference with all users.
$enddate = 2019-04-15;
$startdate = date("Y-m-d", strtotime("-6 months", strtotime($enddate)));
$users = User::all();
$usersIdArray = $users->pluck("id")->all();
$reportedBy = Report::where('date', '>=', $startdate)
->where('date', '<=', $enddate)
->distinct("user_id")->get();
$reportedByIdArray = $reportedBy ->pluck("id")->all();
$notReportedByIdArray = array_values(array_diff($usersIdArray , $reportedByIdArray));
$notREportedUsers = User::whereIn(id", $notReportedByIdArray)->get();
//its a way but not tested
I have modified the query from this answer
I believe the query can be wrote cleaner. I will let you do this if you want to.
App\User::select('*')
->from(\DB::raw("(select
low.*,
low.`date` as date_start,
high.`date` as date_end,
to_days(high.`date`) - to_days(low.`date`) as day_gap,
period_diff(date_format(high.`date`, '%Y%m'),
date_format(low.`date`, '%Y%m')) as month_gap
from reports low, reports high
where high.`date` =
(select
min(`date`)
from reports
where
`date` > low.`date`
and low.user_id = high.user_id
)
) as d")
)->get();
Now you will get all the users with 4 extra fields: date_start; date_end, day_gap and month_gap
If you want the users with a month gap of 6 months you can do this:
App\User::select('*')
->from(\DB::raw("..."))
->where('month_gap', '>=', 6)
->get();

Laravel 5 where condition to get pass 30 days worth of records

I have a date column in the instances table with varchar datatype stored as d-m-Y. In my where condition I am trying to fetch records for just past 30 days only.
$backdate = Carbon::parse('-30 days')->toDateString();
$date30DaysBack = Carbon::parse($backdate)->format('d-m-Y');
$adverts = DB::table('adverts')
->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=',$date30DaysBack)
The full query
$adverts = DB::table('adverts')
->select(DB::raw('(SELECT IF(ext = \'jpeg\', CONCAT(fullpath, \'_1.\', ext), (CONCAT(fullpath,\'.\',ext))) as fullpath FROM advertsstorage where uid_dir = adverts.ad_uid ORDER BY id ASC limit 1)as fullpath, adverts.*, domains.location,instances.date'))
->join('domains','adverts.domain', '=' ,'domains.domain')
->join('advertiser_domains','domains.id', '=' ,'advertiser_domains.domain_id')
->join('advertisers','advertiser_domains.advertiser_id', '=' ,'advertisers.u_id')
->join('instances','adverts.ad_uid','=','instances.ad_uid')
->join('urls','instances.u_id','=','urls.id')
->join('sites','urls.sites_id','=','sites.id')
->where('advertisers.u_id', '=',$advertiserID)
->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=',Carbon::now()->subDays(30)->format('d-m-Y'))
->orderBy(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), 'DESC')
->get();
Did you try DATEDIFF method
$adverts = DB::table('adverts')
->select(DB::raw('(SELECT IF(ext = \'jpeg\', CONCAT(fullpath, \'_1.\', ext), (CONCAT(fullpath,\'.\',ext))) as fullpath FROM advertsstorage where uid_dir = adverts.ad_uid ORDER BY id ASC limit 1)as fullpath, adverts.*, domains.location,instances.date'))
->join('domains','adverts.domain', '=' ,'domains.domain')
->join('advertiser_domains','domains.id', '=' ,'advertiser_domains.domain_id')
->join('advertisers','advertiser_domains.advertiser_id', '=' ,'advertisers.u_id')
->join('instances','adverts.ad_uid','=','instances.ad_uid')
->join('urls','instances.u_id','=','urls.id')
->join('sites','urls.sites_id','=','sites.id')
->where('advertisers.u_id', '=',$advertiserID)
->where(DB::raw('DATEDIFF( now(), STR_TO_DATE(instances.date,"%d-%m-%Y") )'), '<=', 30)
->orderBy(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), 'DESC')
->get();
Have you checked out the Carbon docs?
You can use the subtraction modifier for this; Carbon::now()->subDays(30);.
Would look something like this in your code:
$adverts = DB::table('adverts')->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=', Carbon::now()->subDays(30)->format('d-m-Y'))
Try this.
Carbon has subDays function by which you can get past 30 days data
$date30DaysBack= Carbon::now()->subDays(30)->format('d-m-Y');
$today = Carbon::now()->format('d-m-Y');
$adverts = DB::table('adverts')
->whereBetween(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'),[$date30DaysBack,$today])->get()

Resources