Laravel query builder count rows by day SQL db::raw - php

I've got a Laravel 8 application whereby I need to count the number of total applications for each day and output a count of the data in the most efficient way, for instance, 500 applications on 1st, 1,000 applications on 2nd and so fourth, depending on how many applications there are each day.
I'm using DB::raw() to count my rows, however, Laravel's timestamps by default includes the hours, minutes and seconds as part of the date, and so this isn't going to work for me, I need to format the date to exclude this and just contain the day.
My query doesn't seem to be returning anything, and no error either, so I think there's something wrong with my first DB::raw(), it doesn't seem to be formatted the created_at column at all, what am I missing?
Application::whereBetween('created_at', [$from, $to])
->select(DB::raw('DATE_FORMAT("created_at, %Y-%m-%d")'), DB::raw('count(*) as applications'))
->groupBy('created_at')
->get();

You can use groupByRaw()
Application::whereBetween('created_at', [$from, $to])
->select(DB::raw('DATE_FORMAT(created_at, "%Y-%m-%d")'), DB::raw('count(*) as applications'))
->groupByRaw('DATE_FORMAT(created_at, "%Y-%m-%d")')
->get();
Also, you can use selectRaw() instead of select(DB::raw)

Related

Laravel eloquent grabbing results between two days

I have a model for which I have a database field called day. This is a unique field and it can contain a day like monday, tuesday, and so on. So monday can only be used once, etc. The value is literally stored as a string.
Now I am trying to display only upcoming x results, for example, only the results from the next 3 days. Which means, I want to display the result of today, tomorrow and the day after tomorrow. I have been trying like below:
Model::where('day', '>=', Carbon::now())
->where('day', '<', Carbon::now()->addDays(3))
->get();
But this does not give me any results. I want to prevent having to change the field to a date field, for now. But I was wondering if there is any way to achieve what I am looking for with a simple eloquent query.
if the day is unique you can get the next three days and select their results:
$today=Carbon::now()->dayName;
$tomorrow=Carbon::tomorrow()->dayName;
$afterTomorrow=Carbon::tomorrow()->addDay()->dayName;
$acceptableDays=[$today,$tomorrow,$afterTomorrow];
Model::whereIn('day', $acceptableDays)
->get();
pay attention to letter case, Carbon::now()->dayName; will gave you the day name with first capital letter, you should convert it to match the way it stored in your db

(LARAVEL) Two ORDER BY and a LIMIT

This is some sorting:
Get 20 posts sorted by "views".
AFTER IT FINISH, then go to the next step.
sort it by "created_at".
How to do it?
Heres my current code (which work, but I dont want to use SORTBY) for some reason sortby is not working for other project. if possible i want it to be as one eloquent query:
$this->data['today_post'] = Posts::orderBy('views', 'desc')->whereRaw('created_at >= NOW() - INTERVAL 1 DAY')->limit(20)->get();
$this->data['today_post'] = $this->data['today_post']->sortByDesc('created_at');
This code is not working, because LIMIT is usually applied as the last operation, so the result will first be sorted by "views" and "created_at" and then limited to 20. I dont want that. I want to sort and limit then after all is complete. I want to sort again the last time.
$this->data['today_post'] = Posts::orderBy('views', 'desc')->orderBy('created_at', 'desc')->whereRaw('created_at >= NOW() - INTERVAL 1 DAY')->limit(20)->get();
Thank you so much
You'll still need to use sortBy() or sortByDesc() if you want to use Eloquent. I've just tested this solution and it works perfectly:
Posts::orderBy('views', 'desc')
->where('created_at', '>=', Carbon::now()->subDay())
->take(20)
->get()
->sortByDesc('created_at');

Filter SQL database query by timestamp, backend in PHP using Laravel

So I'm trying to build a query to my SQL database from my backend (that's written in php with Laravel). I have a table in my database with a column that's titled "created_at", carrying values of the 'timestamp'-type. What I want to do is, when I send a query to my database, to only pick the rows (or instances, I guess) of my table that are created 30 days or less from the current date. I've tried experimenting back and forth with the 'where' keyword, but I couldn't get it to work as I wanted it to.
When I browse the table in my database, the dates are written in the format "YYYY-MM-DD hh:mm:ss" but I'm not sure how to compare them when they're in this format, and I don't know how to convert them whilst doing a query. I've looked at the whereBetween() method in Laravel but I didn't get that to work since I didn't know how I would compare them.
At the moment my query looks like this:
$topUser = DB::table('statistics')
->join('users', 'statistics.user_id', '=', 'users.id', 'inner')
->select('fname', 'user_id', DB::raw('sum(price) as total_collection'))
->groupBy('user_id')
->orderBy('total_collection','desc')
->get();
What I want to do, in pseudocode, is something along the lines of;
->where 'created_at' <= 30 days ago
Thanks in advance!
It's basically that simple.
->whereDate('created_at', '<=', \Carbon\Carbon::now()->subDays(30));
You can take advantage of mysql's date functions by using DB::raw
->where('created_at', '<=', DB::raw("DATE_SUB(CURDATE(),INTERVAL 30 DAY)")

Laravel: whereBetween to accept the first date

Scenario:
The startdate and enddata in the database is 2015-07-20 and 2015-07-30 respectively and the query that works properly is,
Model::whereBetween('startdate',array('2015-07-30','2015-08-10'))->get();
The query return 1 record from the table which is the expected result. Now what I expect is a slight change. The query should not retrieve the record by considering the date 2015-07-30 does not fall in between 2015-07-30. How do I achieve this?
whereBetween is inclusive. In order to exclude one of the edges you'll need to build a between query manually:
Model::where('startdate', '>', '2015-07-30')->where('startdate', '<=', '2015-08-10')->get();
Easy Solution
Model::whereBetween(DB::raw('date(startdate)'),array('2015-07-30','2015-08-10'))->get();

Laravel 4 Query with 30 Days Ago Condition

I dont understand where goes wrong. When I add this
where('units.solddate','>=','DATE_SUB(CURDATE(), INTERVAL 30 DAY)')
where clause and my result is empty. I tried in phpMyadmin and it does return results.
$query= (tables)
->select(DB::raw('SUM(units.price) as price, DATE(units.solddate) as date, DAY(units.solddate) as day'))
->where('units.solddate','>=','DATE_SUB(CURDATE(), INTERVAL 30 DAY)')
->where('units.solddate','<=','NOW()')
->groupBy('date')
->get();
Please advice.
The reason why the constraints don't work is that Eloquent takes the value you compare with literally, escapes it when needed and then uses in a query. So if you do
->where('units.solddate','<=','NOW()')
you're in fact comparing units.solddate with a strin NOW(), like in:
... WHERE units.solddate <= 'NOW()'
If you want to use MySQL functions in your query you have to explicitely tell Eloquent/QueryBuilder that you mean the raw value that you provided by using DB::raw() to wrap the value.
The following should work for you:
->where('units.solddate','>=',DB::raw('DATE_SUB(CURDATE(), INTERVAL 30 DAY)'))
->where('units.solddate','<=',DB::raw('NOW()'))

Categories