Laravel - Advanced Carbon Date Query - php

I'm trying to write a certain query but I'm failing with it and I'm looking for some help
Here's what I want to do
SELECT all items WHERE created_at is from before this month (July, June,...), and also select the first 3 which are created during this month
this is what I currently have. I've tried numerous times, but I can't figure out the right "WHERE" case
$offertes = DB::table('offertes')
->select('*')
->where('receiver_id', $user_id)
...
->orderby('seen')
->orderby('created_at','desc')
->get();

Something like this should work:
$time = new Carbon\Carbon('first day of this month'); // Get first day of the month.
$time->setTime(0, 0, 0); // Set time to 00:00:00.
....
->where('created_at', '<', $time)
->where(function($q) {
$q->where('created_at', '>', $time)
->orderby('created_at','asc')
->take(3)
})
->get;

Related

How to add days in querying date? laravel

How can we add days in the date that we're querying using laravel eloquent?
Something like this:
Post::where('created_at + 7 days', now()->toDateTimeString())
->where('created_at', '<', now()->toDateTimeString())
->get();
My logic is like this one
today >= created_at && today <= created_at + 4
Is there some correct syntax to achieve this one?
One of the ways to compare from date time is using the calculated Carbon like below:
Post::where('created_at', '>=', now()->addDays(4)->toDateTimeString()
->get();
It will display only posts which have created_at greater than 4 days from today.
For date range filter, you can use between scope like:
$startDate = now()->subDays(4)->toDateString();
$endDate = now()->toDateString();
$filteredPosts = Post::whereBetween('created_at', [$startDate, $endDate])->get();
For more information about filter, you could visit Laravel Query Builder
You can use whereDate method:
Post::whereDate('created_at', 'like', now()->subDays(4))->get();
or
Post::whereDate('created_at', '>=', now()->subDays(4))->get();

eloquent query condition based on relation

Results(game_id, score)
Games(start, end, threshold)
Given a timestamp:
I want to find all results that belong to a game with a start & end time containing the timestamp time and where the result score is above the game threshold.
I have already managed to query for the time condition, but how can I additionally query for Results.score > games.threshold?
Results::whereHas('game', function($q) use ($timestamp) {
$q->where('start', '<=', $timestamp)
->where('end', '>=', $timestamp)
})->with('game')->get()
Try to use whereRaw inside whereHas and check if it works:
Results::whereHas('game', function($q) use ($timestamp) {
$q->where('start', '<=', $timestamp)
->where('end', '>=', $timestamp)
->whereRaw('results.score > games.threshold');
})->with('game')->get();

Querying Data and Grouping by Day with Laravel

I run a website that stores images and users get a hotlink.
I want to be able to query records made in the last 7 days in the table containing the uploaded image data, extract the created_at column only, and compile the data into an array, similar to making an archive list for a blog.
I would like for the results to be presented like:
[
'Sunday' => 5,
'Monday' => 45,
'Tuesday' => 452,
...
]
Where each number represents the number of records created on each day. As long as I can output an array like that, I can handle the Javascript side easily.
Anybody have any suggestions?
EDIT
This is the code I've tried so far:
<?php
class Admin
{
public function getCreatedAtAttribute($value)
{
$this->attributes['created_at'] = Carbon::createFromFormat('Y-m-d H:i:s', $value);
}
public static function uploadsGraph()
{
$date = \Carbon\Carbon::now();
$uploads = Upload::select('created_at')->where('created_at', '>=', \Carbon\Carbon::now()->subWeek())->get();
foreach($uploads as $date)
{
echo $date->created_at . '<br>';
}
}
}
EDIT 2
Here's another version I tried, but that didn't work out well.
class Admin
{
public static function uploadsGraph()
{
$date = \Carbon\Carbon::now();
$uploadsByDay = DB::table('uploads')
->select(DB::raw('
YEAR(created_at) year,
MONTH(created_at) month,
MONTHNAME(created_at) month_name
'))
->groupBy('year')
->groupBy('month')
->orderBy('year', 'desc')
->orderBy('month', 'desc')
->get();
dd($uploadsByDay);
}
}
I'm assuming that the number next to each day of the week represents the number of records made on that day, with the entire dataset you want to query ranging only over the last 7 days.
The idea here is to select the count of items that were created on the same day (ignoring completely the timestamp portion of the created_at column), so we can use DB::raw inside of a select() call to aggregate all of the entries that were created on a specific day and then restrict that dataset to only those created in the last week. Something like this ought to work:
$data = Upload::select([
// This aggregates the data and makes available a 'count' attribute
DB::raw('count(id) as `count`'),
// This throws away the timestamp portion of the date
DB::raw('DATE(created_at) as day')
// Group these records according to that day
])->groupBy('day')
// And restrict these results to only those created in the last week
->where('created_at', '>=', Carbon\Carbon::now()->subWeeks(1))
->get()
;
$output = [];
foreach($data as $entry) {
$output[$entry->day] = $entry->count;
}
print_r($output);
Also note that I assumed this to be a 'rolling' week, where if today happens to be a Thursday, then the first date in the dataset will be the previous Thursday. It will not start on the most recent Sunday, if that is what you need. If it is, you can change the -where() condition to something like this:
...
->where('created_at', '>=', Carbon\Carbon::parse('last sunday'))
...
DB::table("clicks")
->select("id" ,DB::raw("(COUNT(*)) as total_click"))
->orderBy('created_at')
->groupBy(DB::raw("MONTH(created_at)"))
->get();

Laravel $q->where() between dates

I am trying to get my cron to only get Projects that are due to recur/renew in the next 7 days to send out reminder emails. I've just found out my logic doesn't quite work.
I currently have the query:
$projects = Project::where(function($q){
$q->where('recur_at', '>', date("Y-m-d H:i:s", time() - 604800));
$q->where('status', '<', 5);
$q->where('recur_cancelled', '=', 0);
});
However, I realized what I need to do is something like:
Psudo SQL:
SELECT * FROM projects WHERE recur_at > recur_at - '7 days' AND /* Other status + recurr_cancelled stuff) */
How would I do this in Laravel 4, and using the DATETIME datatype, I've only done this sort of thing using timestamps.
Update:
Managed to solve this after using the following code, Stackoverflow also helps when you can pull bits of code and look at them out of context.
$projects = Project::where(function($q){
$q->where(DB::raw('recur_at BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) AND NOW()'));
$q->where('status', '<', 5);
$q->where('recur_cancelled', '=', 0);
});
Updated Question: Is there better way to do this in Laravel/Eloquent?
Update 2:
The first resolution ended up not been right after further testing, I have now resolved and tested the following solution:
$projects = Project::where(function($q){
$q->where('recur_at', '<=', Carbon::now()->addWeek());
$q->where('recur_at', '!=', "0000-00-00 00:00:00");
$q->where('status', '<', 5);
$q->where('recur_cancelled', '=', 0);
});
You can chain your wheres directly, without function(q). There's also a nice date handling package in laravel, called Carbon. So you could do something like:
$projects = Project::where('recur_at', '>', Carbon::now())
->where('recur_at', '<', Carbon::now()->addWeek())
->where('status', '<', 5)
->where('recur_cancelled', '=', 0)
->get();
Just make sure you require Carbon in composer and you're using Carbon namespace (use Carbon\Carbon;) and it should work.
EDIT:
As Joel said, you could do:
$projects = Project::whereBetween('recur_at', array(Carbon::now(), Carbon::now()->addWeek()))
->where('status', '<', 5)
->where('recur_cancelled', '=', 0)
->get();
Didn't wan to mess with carbon. So here's my solution
$start = new \DateTime('now');
$start->modify('first day of this month');
$end = new \DateTime('now');
$end->modify('last day of this month');
$new_releases = Game::whereBetween('release', array($start, $end))->get();
#Tom : Instead of using 'now' or 'addWeek' if we provide date in following format, it does not give correct records
$projects = Project::whereBetween('recur_at', array(new DateTime('2015-10-16'), new DateTime('2015-10-23')))
->where('status', '<', 5)
->where('recur_cancelled', '=', 0)
->get();
it gives records having date form 2015-10-16 to less than 2015-10-23.
If value of recur_at is 2015-10-23 00:00:00 then only it shows that record
else if it is 2015-10-23 12:00:45 then it is not shown.
Edited: Kindly note that whereBetween('date',$start_date,$end_date) is inclusive of the first date.

Laravel: How to get count of all records created within in current week as of yesterday

I want to get count of one week old created records as of yesterday in laravel using created_at time stamp, I have:
//week date range upto current day
$name_current_day = date("l");
$name_current_week = date("Y-m-d",strtotime('monday this week')).'to'.date("Y-m-d",strtotime("$name_current_day this week"));
//query to get count
foreach($name_list as $name){
//created in week
$data[$network->name.'_week'] = Info::select( DB::raw('DATE(`created_at`) as `date`'),DB::raw('COUNT(*) as `count`'))
->where('created_at', '>', $name_current_week)
->where('name',$name->f_name)
->groupBy('date')
->orderBy('date', 'DESC')
->lists('count', 'date');
}
When I run this query, I am not getting accurate results, Is this the cirrect way to get last 7 days records in Laravel.
You need to compare date() as well, and it's easier to use Carbon, though you don't need that. It's up to you.
EDIT: your question is a bit unclear, but it seems that you don't want week-old, but only current week's results.
Anyway, this will work for you:
// week old results:
// $fromDate = Carbon\Carbon::now()->subDays(8)->format('Y-m-d');
// $tillDate = Carbon\Carbon::now()->subDay()->format('Y-m-d');
// this week results
$fromDate = Carbon\Carbon::now()->subDay()->startOfWeek()->toDateString(); // or ->format(..)
$tillDate = Carbon\Carbon::now()->subDay()->toDateString();
Info::selectRaw('date(created_at) as date, COUNT(*) as count'))
->whereBetween( DB::raw('date(created_at)'), [$fromDate, $tillDate] )
->where('name',$name->f_name)
->groupBy('date')
->orderBy('date', 'DESC')
->lists('count', 'date');
You can use Carbon for this, which makes working with dates easier in Laravel. It's included with the framework. You can then do this:
$yesterday = Carbon::now()->subDays(1);
$one_week_ago = Carbon::now()->subWeeks(1);
foreach($name_list as $name){
//created in week
$data[$network->name.'_week'] = Info::select( DB::raw('DATE(`created_at`) as `date`'),DB::raw('COUNT(*) as `count`'))
->where('created_at', '>=', $one_week_ago)
->where('created_at', '<=', $yesterday)
->where('name',$name->f_name)
->groupBy('date')
->orderBy('date', 'DESC')
->lists('count', 'date');
}

Categories