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

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()

Related

How to write raw query in Laravel?

There is a query:
SELECT ST_DistanceSpheroid(geometry(location), ST_GeomFromText('POINT(37.854289 55.685333)'), 'SPHEROID["WGS 84",6378137,298.257223563]')
FROM users
How to pass parameter 37.854289 55.685333?
Also I tried this:
$point = "37.854289 55.685333";
return DB::table('users')
->select(DB::raw('ST_DistanceSpheroid(geometry(location), ST_GeomFromText(\'POINT(?)\'), \'SPHEROID["WGS 84",6378137,298.257223563]\''), [$point])
->get();
I got this error:
"message": "stripos(): Argument #1 ($haystack) must be of type string, array given",
My attempt bases accepted question:
$lon = 37.857397;
$lat = 55.685333;
return DB::table('users')
->selectRaw(
"(ST_DistanceSpheroid(
geometry(location),
ST_GeomFromText('POINT(? ?)'),
'SPHEROID[?, ?, ?]'
)) as distance",
[$lon, $lat, 'WGS 84', 6378137, 298.257223563]
)->leftJoin('doctors', 'doctors.user_id', 'users.id')->orderBy('distance', 'ASC')->get();
I have got an error:
{
"message": "PDO: SQLSTATE[XX000]: Internal error: 7 ОШИБКА: SPHEROID parser - couldnt parse the spheroid\nLINE 4: 'SPHEROID[?, ?, ?]'\n ^ (SQL: select (ST_DistanceSpheroid(\n geometry(location),\n ST_GeomFromText('POINT(37.857397 55.685333)'),\n 'SPHEROID[WGS 84, 6378137, 298.257223563]'\n )) as distance from \"users\" left join \"doctors\" on \"doctors\".\"user_id\" = \"users\".\"id\" order by \"distance\" asc)"
}
The row query that works:
SELECT doctors.user_id, (ST_DistanceSpheroid(geometry(location), ST_GeomFromText('POINT(37.857397 55.690576)'), 'SPHEROID["WGS 84",6378137,298.257223563]')
) as distance FROM users INNER JOIN doctors ON doctors.user_id = users.id ORDER BY distance ASC
You almost got it. The [$point] parameter should be the second parameter of DB::raw($query, $bindings) but you added it as a second parameter to select().
// What you have
->select(DB::raw(...), [$point])
// correct syntax
->select(DB::raw(..., [$point]))
If you've got nothing else to put in your select clause, might as well use selectRaw(). It's the same as select(DB::raw()).
DB::table('users')
->selectRaw('ST_DistanceSpheroid(geometry(location), ST_GeomFromText(\'POINT(?)\'), \'SPHEROID["WGS 84",6378137,298.257223563]\')', [$point])
Personally, I'd write the query like this:
$query = DB::table('users')
->selectRaw(
"ST_DistanceSpheroid(
geometry(location),
ST_GeomFromText('POINT(? ?)'),
'SPHEROID[?, ?, ?]'
)",
[37.854289, 55.685333, 'WGS 84', 6378137, 298.257223563]
)
->get();

Converting date to mothname, day, year with like() codeigniter 4

I'm using ci4 and I want to get the month name on search with like() method:
I tried this but did not work:
table column = p.date = '2021-05-18 01:07:50'
$this->like(date('F', strtotime('p.date')), date('F', strtotime('18-05-2021'));
//createdon - 2020-06-15 02:19:40
$this->db->where('month(createdon)',6);
$result = $this->db->get('yourtablename')->result();

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

how to retrieve different names from same table with different ids on join laravel

I need to get names from destinations table for each from_destination_id and to_destination_id
as fromDestinationName and toDestinationName
$bookingTransfersData = DB::table('transfers as t')
->select('t.periodStart as periodStart', 't.periodEnd as periodEnd','t.days','t.transfer_id','t.cost_round_trip',
't.cost_one_way','t.status','d.destination_id as destinationId','d.name as destinationName', 't.type',
'tf.name as officeName', 'ag.name as agencyName', 'u.name as userName', 'v.name as vehicleName')
->join('destinations as d', function ($join){
$join->on('t.from_destination_id','=','d.destination_id')
->orOn('t.to_destination_id','=','d.destination_id');
})->join('vehicles as v','t.vehicle_id','=','v.vehicle_id')
->join('transfer_offices as tf','t.office_id','=','tf.transfer_office_id')
->join('agencies as ag','t.forAgency_id','=','ag.agency_id')
->join('users as u','t.addedBy_user_id','=','u.id')
->get();
i want to get the names of each id after this results
$searchResults = $bookingTransfersData
->where('periodStart','between', $periodStart && $periodEnd)
->where('periodEnd','between', $periodStart && $periodEnd)
->where('destinationName','=',$from_destination_name && $to_destination_name)->where('type','like', $type);
like:
$fromDestinationName = $searchResults->pluck('from_destination_id','destinationName')
->where('from_destination_id','=','destinationId');
but $fromDestinationName return an empty collection
please help :)
I solved it by removing this join:
->join('destinations as d', function ($join){
$join->on('t.from_destination_id','=','d.destination_id')
->orOn('t.to_destination_id','=','d.destination_id');
})
and add for each destionation_id a join to retrive each name
and this will not work if I don't add for table name that i joined two times as to name it new name like
'destinations as d1' and 'destinations as d2'
$bookingTransfersData = DB::table('transfers as t')
->select('t.periodStart as periodStart', 't.periodEnd as periodEnd','t.days','t.transfer_id','t.cost_round_trip',
't.cost_one_way','t.status','d1.destination_id as fromDestinationId','d1.name as fromDestinationName', 't.type',
't.to_destination_id','tf.name as officeName', 'ag.name as agencyName', 'u.name as userName', 'v.name as vehicleName',
't.from_destination_id', 'd2.destination_id as toDestinationId','d2.name as toDestinationName')
->join('destinations as d1','t.from_destination_id','=','d1.destination_id')
->join('destinations as d2','t.to_destination_id','=','d2.destination_id')
->join('vehicles as v','t.vehicle_id','=','v.vehicle_id')
->join('transfer_offices as tf','t.office_id','=','tf.transfer_office_id')
->join('agencies as ag','t.forAgency_id','=','ag.agency_id')
->join('users as u','t.addedBy_user_id','=','u.id')->get();
the problem solved :)

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();

Resources