In my Laravel 5 app I've got a relationship, and from this one-to-many relationship, I want to query and get only results whose date diff between their creation_date and an arbitrary date is between 0 and 2 days.
If you need I can show you a pseudocode, even if I think that it's clear what I need.
Thank you!
Just create a arbitrary date using carbon (as you are using laravel):
$start = Carbon\Carbon::create(year,month,day);
$end = $start->copy()->addDays(2);
And a little DB::raw in the mix, to format the created_at field to your needs:
Model::where(DB::raw('DATE_FORMAT(created_at,"%Y-%m-%d")'),'>=',$start)->where(DB::raw('DATE_FORMAT(created_at,"%Y-%m-%d")'),'<=',$end)->get();
That's it.
Related
In my database a have a table with a column called date. In the date columns are datetime entries stored. Now I want to write a query that gets me all entries from a day.
Now If I do it like that I obviously get just the records with exact same timestamp
$date = Carbon::now()->startOfDay();
Task::where('date', $date)->get()->all();
But I need all records where the date is the same, no matter which timestamp they have
Laravel has a whereDate function, which is what you're looking for:
Task::whereDate('date', $date->toDateString())->get();
However, Eloquent may cause some issues since you have the column named date, and it automatically scopes the where clauses for you. In that case, you'll need a raw command:
Task::whereRaw('DATE(`date`) = ?', [$date->toDateString()])->get();
I'm trying to fetch rows based on the "created_at" field that are older than (for example) 2 days.
I'm using Laravel Eloquent. Can somebody help me with this?
You can use Carbon subDays() like below:
$data = YOURMODEL::where('created_at', '<=', Carbon::now()->subDays(2)->toDateTimeString())->get();
You can use the whereDate() eloquent method to run a query against dates.
Model::whereDate('created_at', '<=', now()->subDays(2)->setTime(0, 0, 0)->toDateTimeString())->get();
The now() is a laravel helper function to get a carbon instance of the current date and time.
NOTE: We set the time using the setTime() method so that it starts from the beginning of the day.
Update: It is also possible to use ->startOfDay().
How can I retrieved records from the database using carbon dates with the specified date range e.g retrieved records from "2014-10-13" to "2015-11-18"? any ideas, help, suggestions, clues, recommendations please?
You can use the whereBetween method. So, just as an example, lets say you have two Carbon dates.
$earlier = Carbon::yesterday();
$later = Carbon::today();
Model::whereBetween('column', [$earlier, $later])->get();
The first parameter represents the column you are checking. The second parameter is an array of the two dates.
Using the dates in your question, you can generate the carbon dates like this:
$earlier = Carbon::parse('2015-09-11');
$later = Carbon::parse('2015-09-14');
Model::whereBetween('column', [$earlier, $later])->get();
The parse method is pretty awesome.
I have a field in my database called "deadline" which is of DATE format, and I want to use Eloquent to say that if the deadline field does not match Carbon::now(); but isn't in the future then don't show this row.
How can I achieve this?
Select records where deadline is greater than or equal to today's date() in the Y-m-d format.
Model::where('deadline','>=', date('Y-m-d'))->get();
Laravel works with Carbon for formatting timestamps etc, which you can easily set the deadline column as one of those Carbon objects with a Laravel date mutator allowing you formatting abilities.
But for a select statement, i'd just use the above personally.
My application is built using Laravel 4.1 and supports pretty much all databases that Laravel officially does today. I have an INT(10) column that stores the Unix timestamp for each "post" to indicate the create time of the post.
Is there a way I can get the daily number of posts out of this sort of setup? Basically, I want to make a graph out of Google Chart API to indicate the trend of number of posts made per day for the last 1 month.
Also, I am not looking for a solution around DB::raw(), I'd prefer using the query builder.
If you want to perform an aggregation on the db-side IMHO you'll have to use DB::raw() because you need to manipulate your timestamp values.
If understand correctly your major concern is not in using DB::raw() method but rather not using vendor specific datetime functions (like FROM_UNIXTIME() in MySQL).
You can issue a query like this to get aggregated results in an almost db agnostic way (AFAIK all major DBMSes have implementation for FLOOR() function)
SELECT FLOOR(timestamp / 86400) AS date , COUNT(*) AS total
FROM post
GROUP BY FLOOR(timestamp / 86400)
which translates into something like this with Query Builder
$result = DB::table('posts')
->select(DB::raw('FLOOR(timestamp / 86400) AS date, COUNT(*) AS total'))
->groupBy(DB::raw('FLOOR(timestamp / 86400) AS date, COUNT(*) AS total'))
->get();
Sample output:
| DATE | TOTAL |
|-------|-------|
| 16081 | 2 |
| 16082 | 3 |
Here is SQLFiddle demo
And then in the client code convert date column value into a human readable form by
date('m/d/Y', 16081 * 86400)
while you iterate over the resultset.
Firstly, you should probably using Laravel's built in timestamps for created_at and updated_at columns. If you don't want to use Laravel's built in timestamps, you should at least be setting your timestamp columns to the timestamp datatype rather than int.
With that said, the raw SQL you'd probably want to use for something like this would look a bit like;
SELECT DATE(timestamp_column_name) as day, count(*) as post_count from posts group by day order by day asc;
There's no real, pure Eloquent way of doing this. Something like the following is going to be as close as you'll get.
Post::groupBy('day')->get([
DB::raw('DATE(FROM_UNIXTIME(timestamp_column_name)) as day'),
DB::raw('count(*) as post_count')
]);
This will return two columns, day being the date in YYYY-MM-DD format, and post_count being an integer with the count.
===========
In the above example, I am using the MySQL DATE function. You can of course manipulate your timestamp column however you want however you want. This just seemed to make the most sense to me.