Need equivalent for (non-existent) whereHour command in Laravel - php

I use the following SQL query to return a set of data (upcoming sessions):
SELECT * FROM availabilities
WHERE
name = "Booked"
and
start_time >= (DATE_ADD(NOW(), INTERVAL 1 DAY))
and
DAY(start_time) >= (DAY(DATE_ADD(NOW(), INTERVAL 1 DAY)))
and
HOUR(start_time) = (HOUR(DATE_ADD(NOW(), INTERVAL 1 DAY)));
This returns the data I need (upcoming sessions 24 hours in advance) but I am struggling to get this into a format that can return the same data in Laravel (using 5.3).
I have this as a start:
$UpcomingSessions = Availability::where('name', '=', 'booked')
->where("start_time",">=", '(DATE_ADD(NOW(), INTERVAL 1 DAY))')
->whereDay("start_time",">=", '(DAY(DATE_ADD(NOW(), INTERVAL 1 DAY)))')
->where("start_time",">=", '(DATE_SUB(NOW(),INTERVAL 1 HOUR))')
->get();
But can't figure out what to do with the hour part as there is no
whereHour
in Laravel.
If I try:
->where("HOUR(start_time)",">=", '(HOUR(DATE_ADD(NOW(), INTERVAL 1 DAY)))')
I get the following message:
Column not found: 1054 Unknown column 'HOUR(start_time)' in 'where clause'
Is there an equivalent command for whereHour that I could use perhaps? Any ideas on how to format the SQL correctly would be great!

Laravel 8.x here.
From the Docs, there is a whereTime() function.
$users = DB::table('users')
->whereTime('created_at', '=', '11:20:45')
->get();
The value given as the second parameter could be any formatted string. So you could, for instance, just narrow it down to 2 whereTime() calls:
$users = DB::table('users')
->whereTime('created_at', '>=', '11:00:00')
->whereTime('created_at', '<', '12:00:00')
->get();

Hey what if you try to use https://laravel.com/docs/5.8/queries#raw-expressions
->where(DB:raw("HOUR(start_time) >= '(HOUR(DATE_ADD(NOW(), INTERVAL 1 DAY)))'))
or
->whereRaw()

Related

How to transform sql query into Query Builder Laravel way?

I need to convert this query into Laravel query builder or ORM
SET #start_date = '2020-11-01';
SET #end_date = '2020-11-08';
SET #duration = CONVERT(#end_date, DATE) - CONVERT(#start_date, DATE);
SELECT item_id, days
FROM (
SELECT item_id, sum(end_date - start_date) AS days
FROM schedule WHERE start_date >= #start_date AND end_date <= #end_date
GROUP BY item_id) AS virtual
WHERE days = #duration;
(i use Laravel 8)
i could not find similar example I could analize and try by myself :(
i try this :
$res = DB::table('schedule')
->select('schedule.item_id' , DB::raw("SUM(schedule.end_date - schedule.start_date) as days"))
->where('start_date', '>=', $start_date)
->where('end_date', '<=', $end_date)
->groupBy('item_id')
->where('days', '=', $duration)
->get();
but i get error :
Column not found: 1054 Unknown column 'days' in 'where clause'
ok i know what is wrong
i tried to access 'days' column before it is created with AS
that column will be available after line ->get() is executed.
So I changed order of these 2 lines :
->where('days', '=', $duration)
->get();
to
->get()
->where('days', '=', $duration);
and now works :)

Laravel DB get() is slow

So i try to get around 5k records, u made this code:
$mainData = DB::table('table')
->where('id', $id)
->where('status', '>', 0)
->where('amount', '>', 0)
->orderBy('timestamp', 'DESC')
->where('status', '>=', DB::raw('UNIX_TIMESTAMP((LAST_DAY(DATE_SUB(NOW(), INTERVAL ' . intval($month) . ' MONTH))+INTERVAL 1 DAY)-INTERVAL 1 MONTH)'))
->where('status', '<', DB::raw('UNIX_TIMESTAMP(LAST_DAY(DATE_SUB(NOW(), INTERVAL ' . intval($month) . ' MONTH))+INTERVAL 1 DAY)'))
->get();
when i made ->toSql() i got this query:
select * from `table` where `id` = 3 and `status` > 0 and `amount` > 0 and `status` >= UNIX_TIMESTAMP((LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH))+INTERVAL 1 DAY)-INTERVAL 1 MONTH) and `status` < UNIX_TIMESTAMP(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH))+INTERVAL 1 DAY) order by `timestamp` desc
when i executed this query in phpmyadmin:
Showing rows 0 - 24 (5980 total, Query took 0.0513 seconds.) but when i run this query in laravel it took around 6 seconds(for only 6k records) i think problem is can be fact that laravel create new object per record is any way to speedup this?
You could try and optimise your code by re-writing more of it into raw queries or rewriting the entire query into raw SQL. Like you mentioned, Laravel is having to create thousands of objects and this really slows the process down which is what you're experiencing.
Take a look at Raw Expressions on the Laravel docs to read more about this.
Basic example from docs:
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
Maybe also trim down the amount of data that is being returned by supplying an array of fields to ->get(). You can take a look at the API for doing that on the Laravel Eloquent Builder API Documentation.
It is fast in phpMyAdmin because it returns paged results and not creating any php objects, as you have pointed.
Instead of using get() use paginate() for paged results or to get all records with a single field use pluck(), e.g. pluck('name', 'id'), which will return an associative array keyed by id.

Having trouble getting records using Laravel

I have the following MySQL query:
SELECT COUNT(id) FROM `tblname` WHERE date >= CURDATE() - INTERVAL 1 DAY;
When I run that in MySQL it gives me the number of records for the past day.
I'm trying to do this in Laravel, because it's included in the WHMCS software I'm using, and can't really understand how to make it work.
Sometimes, when you are stuck in Laravel, just paste your SQL into a raw query like
$result = DB::select("SELECT COUNT(id) FROM `tblname` WHERE date >= CURDATE() - INTERVAL 1 DAY");
Using a query builder
$result = DB::table('tblname')
->whereDate('date', '>=', Carbon::today())
->whereDate('date', '<=', Carbon::tomorrow())
->count();
You can use carbon like
$query = DB::table('your table')->whereDate('date', '>=', Carbon::today())->whereDate('date', '<=', Carbon::tomorrow())->count();

Get data from the last 8 hours in a datetime column Eloquent

I have a query using Laravel's Eloquent and I need a where clause that will get the data from the last 8 hours since the current timestamp. I can easily do that in a raw query like:
SELECT * FROM task_tracker.tasks WHERE created_at > DATE_ADD(NOW(), INTERVAL -8 HOUR);
But how do I do that in an eloquent format? The tasks.created_at is a Datetime Format. I have this currently:
$tasks = Task::join('users', 'tasks.added_by', '=', 'users.id')
->join('users AS x', 'x.id', '=', 'tasks.assigned_to')
->select([
'tasks.id',
'tasks.task_description',
'tasks.start_timestamp',
'tasks.end_timestamp',
'tasks.status',
'users.name',
'x.name AS assign',
'tasks.created_at'
// ])->where('tasks.created_at', '>', 'DATE_ADD(NOW(), INTERVAL -8 HOUR)');
])->where(DB::raw('tasks.created_at', '=', 'DATE_ADD(NOW(), INTERVAL -8 HOUR)' ));
dd($tasks);
I tried using DB::raw and a plain encloure in a single quote (the commented line) but does not work and doesn't get any data. I am using MySQL.
DB::raw has one parameter so try whereRaw like this:
->whereRaw('tasks.created_at = DATE_ADD(NOW(), INTERVAL -8 HOUR')

Get record from database inserted in last two hours using Laravel 5.1

I want to get all the record from the database inserted in last two hours in Laravel 5.1. I am able to get the record for last 1 hour by using the following code:
$all_bridal_requests_check2 = \DB::table('bridal_requests')
->where(function($query)
{
$query->where('publisher', '=', 'bq-quotes.sb.com')
->orWhere('publisher', '=', 'bq-wd.com-bsf');
})
->where('created_on', '>=', \Carbon\Carbon::now()->subHour())
->orderBy('created_on', 'desc')
->get();
use MySQL NOW() or INTERVAL
WHERE `created_on` > NOW() - INTERVAL 2 HOUR
in Laravel
->where('created_on', '>', NOW() - INTERVAL 2 HOUR)
Instead of "subHour", use "subHours(2)"
->where('created_on', '>=', \Carbon\Carbon::now()->subHours(2))
Try this:
$all_bridal_requests_check2 = \DB::table('bridal_requests')
->where(function($query)
{
$query->where('publisher', '=', 'bq-quotes.sb.com')
->orWhere('publisher', '=', 'bq-wd.com-bsf');
})
->where(\DB::raw('date >= DATE_SUB(NOW(), INTERVAL 2 HOUR)')) ->count()
->orderBy('created_on', 'desc')
->get();

Categories