laravel query: orWhere: double condition - php

I have the following query, which does not give me the expected result:
$query = $query->join('events_dates', function($join) use ($data){
$join->on('events.id', '=', 'events_dates.event_id')
->where('events_dates.start_date', "<=", date_format(date_create($data['date_end']), "Y-m-d"))
->where('events_dates.end_date', '>=', date_format(date_create($data['date_start']), "Y-m-d"))
->orWhere('recurrent', "=", 1)
->where((strtotime($data["date_start"]) - strtotime('event_dates.start_date')) % ('events_dates.repeat_interval' * 86400), '=', 0);
});
There are 4 where clauses in this query.
The requirement is that either the two first where clauses are executed, or either two last depending on the recurrentfield.
PHP returns an error division by zero, because the last Where clause should not be executed when recurrentis 0.
Any suggestions?

I don't know your exact goal nor do I know what your db looks so this is just a wild guess:
$query = $query->join('events_dates', function($join) use ($data){
$join->on('events.id', '=', 'events_dates.event_id')
->where('events_dates.start_date', "<=", date_format(date_create($data['date_end']), "Y-m-d"))
->where('events_dates.end_date', '>=', date_format(date_create($data['date_start']), "Y-m-d"))
->orWhere('recurrent', "=", 1)
->whereRaw('DATEDIFF(?, event_dates.start_date) % event_dates.repeat_interval = 0', array($data['date_start']));
Update
This might help for the between two dates part
->where('events_dates.start_date', '<=', new Carbon($data['date_end']))
->where('events_dates.end_date', '>=', new Carbon($data['date_start']))

Related

Laravel sum from relationship with condition

I have the following query where I have a conditional query with relation between two models. I need sum of column hours from the attendance where the conditions are met. I have tried the following, but it's not working.
$users = User::with('attendance')
->whereHas('attendance', function (Builder $query) use ($end, $start) {
$query->whereBetween('date', [$start, $end])
->where('status', 2)
->select(DB::raw('SUM(hours) as h'));
})->orderBy('name')
->where('status', 0)
->get();
In my blade
#foreach($users as $user)
{{ $user->h }}
#endforeach
Please help
User::whereHas('attendance')
->withSum(['attendance' => function ($query) use ($start, $end){
$query->whereBetween('date', [$start, $end])
->where('status', 2);
}], 'hours')
->get();
you can access sum hours using attendance_sum_hours property
({relation}_{function}_{column})
$user->attendance_sum_hours
Tip:
one more thing; $query->whereBetween('date', [$start, $end]) be carefull when using whereBetween on datetime column because will compare also the time, so the results won't be favorable
use whereBetweenColumn('date(date)', [$start, $end])
I do not think you can do this with whereHas, but this is how you would do it using joins. This would return all users that have an attendance between 2 dates and then give you the count.
$users = User::with('attendances')
->selectRaw('users.*, SUM(attendances.hours) as hours_sum')
->leftJoin('attendances', 'users.id', 'attendances.user_id')
->whereBetween('attendances.date', [$startDate, $endDate])
->groupBy('users.id')
->get();
However, if you want to return all users but if they have no attendance it will return 0 you can do the following
$users = User::with('attendances')
->selectRaw('users.*, COALESCE(SUM(attendances.hours), 0) as hours_sum')
->leftJoin('attendances', function (JoinClause $joinClause) {
$joinClause->on('users.id', 'attendances.user_id')
->whereBetween('attendances.date', [$startDate, $endDate]);
})
->groupBy('users.id')
->get();

Filter record by using array - Laravel

I have a collection and I want to filter that collection based upon "days_since_last_wallet_transaction" by using an array. For example, I have an array $day = array(2,4,6,8). Now I want to get the record where days_since_last_wallet_transaction is in 2,4,6,8. I think I cannot use "days_since_last_wallet_transaction" in where clause. Here is my query:
Customer::select(
'customers.id',
'customers.wallet_amount',
'customers.onesignal_id',
'customers.phone_number',
'customers.name',
DB::raw('DATEDIFF(NOW(), max(wallet_transactions.created_at)) as days_since_last_wallet_transaction')
)
->join('wallet_transactions', function ($join){
$join->on('customers.id', '=', 'wallet_transactions.customer_id')
->where('wallet_transactions.amount', '>', 0);
})
->groupBy('customers.id')
->where('customers.wallet_amount', '>', 0);
Any help would be highly appreciable.
Considering below your array:
$days = [2,4,6,8];
create a raw query as below (Note: you can write this line in query also )
$raw_query = '(DATEDIFF(NOW(), max(wallet_transactions.created_at))) IN ('.implode(',',$days).')';
Your query
Customer::select(
'customers.id',
'customers.wallet_amount',
'customers.onesignal_id',
'customers.phone_number',
'customers.name',
DB::raw('DATEDIFF(NOW(), max(wallet_transactions.created_at)) as days_since_last_wallet_transaction')
)
->join('wallet_transactions', function ($join){
$join->on('customers.id', '=', 'wallet_transactions.customer_id')
->where('wallet_transactions.amount', '>', 0);
})
->where('customers.wallet_amount', '>', 0)
->havingRaw($raw_query)
->groupBy('customers.id');

Laravel Database query returns empty collection

I have a small table and try to use some filters to get some specific data out of it.
My attempt:
$matchingCars = Car::where([
['brand', '=', request('brand')],
['model', '=', request('model')],
['price', '<', request('maxPrice')],
])->get();
Result:
Collection {#249 ▼
#items: []
}
You can see nothing is returned. However, if I do the queries one by one and count the result, then I get a number higher than 0, so there are models who pass my filters!
$checkBrands = Car::where('brand', '=', request('brand'))->get();
$checkModels = Car::where('model', '=', request('model'))->get();
$checkPrice = Car::where('price', '<', request('maxPrice'))->get();
echo count($checkBrands) . "<br>"; //output: 1
echo count($checkModels). "<br>"; //output: 1
echo count($checkPrice). "<br>"; //output: 8
die;
Why are they not stored in the collection?
You need to orWhere():-
$matchingCars = Car::where('brand', '=', request('brand'))
->orwhere('model', '=', request('model'))
->orwhere('price', '<', request('maxPrice'))->get()
Note:-
you said:- However, if I do the queries one by one and count the result, then I get a number higher than 0
But this doesn't mean that combination of all these three queries with AND will return result.
So apply OR condition like above.
Try this:
$matchingCars = Car::where('brand', '=', request('brand'))
->where('model', '=', request('model'))
->where('price', '<', request('maxPrice'))->get();
$matchingCars = Car::where('brand', '=', request('brand'))
->where('model', '=', request('model'))
->where('price', '<', request('maxPrice'))->get();
And make sure that that you have the right things returned by request()

Laravel query builder count

I'm using Laravels query builder to retrieve a list of items with some filter options - I need to do a count inside of this query:
$f = DB::table('Likes')
->join('Freestyle', 'Likes.FreestyleID', '=', 'Freestyle.id')
->join('Beat', 'Freestyle.BeatId', '=', 'Beat.id')
->join('Track', 'Beat.TrackId', '=', 'Track.id')
->join('Genre', 'Track.GenreId', '=', 'Genre.id')
->select('Likes.freestyleID as likeFreestyleID', 'Freestyle.*', 'Beat.TrackId as UseMeForTrack',
'Genre.id as GenreID')
->where('Freestyle.Active', '1')
->where('Freestyle.created_at', '>', "$dateScope")
->whereNull('Freestyle.deleted_at')
->whereIn('GenreID', $request->genre)
->first();
To count the amount of times the 'FreestyleID' appears in the likes table.
is this possible? The data returned is perfect I just need the amount of likes a freestyle has, where the FreestyleID in the likes table is null.
Something like this :
$f = DB::table('Likes')
->join('Freestyle', 'Likes.FreestyleID', '=', 'Freestyle.id')
->join('Beat', 'Freestyle.BeatId', '=', 'Beat.id')
->join('Track', 'Beat.TrackId', '=', 'Track.id')
->join('Genre', 'Track.GenreId', '=', 'Genre.id')
->select('Likes.freestyleID as likeFreestyleID','count(Likes.FreestyleID)', 'Freestyle.*', 'Beat.TrackId as UseMeForTrack',
'Genre.id as GenreID')
->where('Freestyle.Active', '1')
->where('Freestyle.created_at', '>', "$dateScope")
->whereNull('Freestyle.deleted_at')
->whereIn('GenreID', $request->genre)
->first();
I think you should be able to use a raw expression like this:
$f = DB::table('Likes')
->join('Freestyle', 'Likes.FreestyleID', '=', 'Freestyle.id')
->join('Beat', 'Freestyle.BeatId', '=', 'Beat.id')
->join('Track', 'Beat.TrackId', '=', 'Track.id')
->join('Genre', 'Track.GenreId', '=', 'Genre.id')
->select(DB::raw('COUNT(likes.FreestyleID) as num_likes'), 'Likes.freestyleID as likeFreestyleID', 'Freestyle.*', 'Beat.TrackId as UseMeForTrack',
'Genre.id as GenreID')
->where('Freestyle.Active', '1')
->where('Freestyle.created_at', '>', "$dateScope")
->whereNull('Freestyle.deleted_at')
->whereIn('GenreID', $request->genre)
->groupBy('Freestyle.id')
->first();

selects, joins, & wheres in Laravel

I'm trying to select specific columns from two tables however when I add the ->select() method into my query, I get an error.
If I leave out the ->select() method, I get a valid resultset and everything works, but adding the select breaks it. Sadly the error reported has nothing to do with the query and is useless to me.
Here is the code that works:
$notifications = DB::table('notifications')
->join('notifications_pivot', function($join)
{
$join->on('notifications.id', '=', 'notifications_pivot.notification_id')
->where('notifications_pivot.user_id', '=', Session::get('id'))
->where('notifications_pivot.is_read', '=', 'N');
})
->get();
Now here's the code that breaks:
$notifications = DB::table('notifications')
->join('notifications_pivot', function($join)
{
$join->on('notifications.id', '=', 'notifications_pivot.notification_id')
->where('notifications_pivot.user_id', '=', Session::get('id'))
->where('notifications_pivot.is_read', '=', 'N');
})
->select(DB::raw('notifications.id, notifications.subject, notifications.message, notifications.url,
notifications.start_date, notifications.end_date, notifications.access_role_id, notifications_pivot.id,
notifcations_pivot.notification_id, notifications_pivot.user_id, notifications_pivot.is_read'))
->get();
It's times like these when I wish I could just write straight SQL and parse the query!
Any suggestions?
Take out the DB::raw() and just pass the fields you want as parameters.
If that doesn't work, the Laravel log at app/storage/logs/laravel.log may provide more insight.
$notifications = DB::table('notifications')
->join('notifications_pivot', function($join)
{
$join->on('notifications.id', '=', 'notifications_pivot.notification_id')
->where('notifications_pivot.user_id', '=', Session::get('id'))
->where('notifications_pivot.is_read', '=', 'N');
})
->select('notifications.id', 'notifications.subject', 'notifications.message', 'notifications.url', 'notifications.start_date', 'notifications.end_date', 'notifications.access_role_id', 'notifications_pivot.id', 'notifcations_pivot.notification_id', 'notifications_pivot.user_id', 'notifications_pivot.is_read')
->get();

Categories