can u post, what u want to be results? a couple of examples for different input data
SQL - WHERE IF condition in QUERY BUILDER request
Hello everyone,
Since many days I'm trying to make a complex request to filter some values but without success. I'm here now to find some help and if you have a some answers for me :)
I have a table "user_working_locations" to store default locations for each day of the week and also to store a custom location for a specific date as you can see below :
id user_id location_id day date type
1 1 1 1 NULL 'default'
2 1 1 2 NULL 'default'
3 1 1 3 NULL 'default'
4 1 1 4 NULL 'default'
5 1 1 5 NULL 'default'
6 1 1 6 NULL 'default'
7 1 1 7 NULL 'default'
8 1 5 5 2021-02-19 'custom'
I want to be able to filter the request with one or several "location_id" with always the start and end date. That means that if for a specific date the user has a custom location, I want to filter on this value but if the user doesn't have a custom location I want to filter on the default value.
You can see my request bellow with what I am able to filter on "location_id = 5" but if I want to filter with "location_id = 1" the query return one result and I'm expecting to have no result because the user has a custom location id = 5 on that day.
$query->whereHas('workingLocations', function($query) use($days, $values) {
$query->whereIn('location_id', $values)
->whereIn('day', $days)
->whereRaw('CASE WHEN date BETWEEN \''.$this->start_date.'\' AND
\''.$this->end_date.'\' THEN type = \'custom\'
ELSE type = \'default\' END');
Many thanks for your help!
My try:
Route::get('/test', function () {
$startDate = '2021-02-22';
$endDate = '2021-02-22';
$days = [1];
$locations = [5];
$constraints = function ($query) use ($locations, $days, $startDate, $endDate) {
$query->whereIn('location_id', $locations);
$query->whereIn('day', $days);
$model = $query->getModel();
$query->where(function ($query) use ($model, $startDate, $endDate) {
$query->orWhere(function ($query) use ($startDate, $endDate) {
$query->where('type', 'custom');
$query->whereBetween('date', [$startDate, $endDate]);
});
$query->orWhere(function ($query) use ($model, $startDate, $endDate) {
$query->where('type', 'default');
$query->whereNotExists(function ($query) use ($model, $startDate, $endDate) {
$query->selectRaw(1);
$query->from($model->getTable(), 'inner');
$query->whereColumn('user_id', $model->qualifyColumn('user_id'));
$query->whereColumn('day', $model->qualifyColumn('day'));
$query->whereColumn('location_id', '<>', $model->qualifyColumn('location_id'));
$query->where('type', 'custom');
$query->whereBetween('date', [$startDate, $endDate]);
});
});
});
};
return \App\Models\User::query()
->with(['workingLocations' => $constraints])
->whereHas('workingLocations', $constraints)
->get();
});
Basically it checks if there is a "custom" record within the dates OR there is not a custom record on a different location for the same date.
Hope this helps.
Please or to participate in this conversation.