Laravel QueryBuilder condition - sql

In Laravel, I want to build a query like following.
There is a status column, value should be 0 or 1.
And there is another column, device_ids with array.
Now,in query, I want to apply different logic on device_ids, when status is 0 and status is 1.
Can someone suggest me best possible way.
$builder->where('status','0')->whereJsonDoesntContain('device_ids', $imei_id->id)
$builder->where('status','1')->whereJsonContains('device_ids', $imei_id->id)
How can I combine both ?
$all_applications = $builder->where('status', $model->status)
->when($status, function ($query) {
Log::error("One");
return $query->whereJsonContains('device_ids', 107); },
function($query) {
Log::error("Zero"); return $query
->whereJsonDoesntContain('device_ids', 107); });
If I use $model->status , it gives me error like , "Undefined variable: model"

You have to use when.
$result = YourModel::where('status', $status)
->when($status, function ($query) {
return $query->whereJsonContains('device_ids', $imei_id->id);
}, function ($query) {
return $query->whereJsonDoesntContain('device_ids', $imei_id->id);
});

Related

Laravel orWhereIn multiple condition with enclosure

My table "companies" has some many columns including position_id, position_id1, position_id2. So I need in Laravel to generate AND condition with 2 ORs. So when I search for companies with any of position_ids=[1,2,3] I'd SQL query will be "...AND (c.position_id in (1,2,3) OR c.position_id1 in (1,2,3) OR c.position_id2 in (1,2,3))".
Here is my PHP code which doesn't work (different combinations):
$position_ids = [1,2,3];
$companies = $companies->whereIn(function ($q) use ($position_ids) {
$q->whereIn('c.position_id', $position_ids)
->orWhereIn('c.position_id1', $position_ids)
->orWhereIn('c.position_id2', $position_ids);
});
$companies = $companies->orWhereIn(function ($q) use ($position_ids) {
$q->orWhereIn('c.position_id', $position_ids)
->orWhereIn('c.position_id1', $position_ids)
->orWhereIn('c.position_id2', $position_ids);
});
$companies = $companies->whereIn(function ($q) use ($position_ids) {
$q->orWhereIn('c.position_id', $position_ids)
->orWhereIn('c.position_id1', $position_ids)
->orWhereIn('c.position_id2', $position_ids);
});
And all the combinations above are getting the same error:
I am getting: Too few arguments to function Illuminate\Database\Query\Builder::whereIn(), 1 passed in ...\app\Http\Controllers\CompanyController.php on line 621 and at least 2 expected.
How to fix it? Thanks.
whereIn() function needs two argument
$companies->whereIn('id', function ($q) use ($position_ids) {
$q->whereIn('c.position_id', $position_ids)
->orWhereIn('c.position_id1', $position_ids)
->orWhereIn('c.position_id2', $position_ids);
});

Can Laravel automatically switch between column = ? and column IS NULL depending on value?

When building a complex SQL query for Laravel, using ? as placeholders for parameters is great. However when the value is null, the SQL syntax needs to be changed from = ? to IS NULL. Plus, since the number of parameters is one less, I need to pass a different array.
To get it to work, I have written it like this, but there must be a better way:
if ($cohortId === null) {
// sql should be: column IS NULL
$sqlCohortString = "IS NULL";
$params = [
Carbon::today()->subDays(90),
// no cohort id here
];
} else {
// sql should be: column = ?
$sqlCohortString = "= ?";
$params = [
Carbon::today()->subDays(90),
$cohortId
];
}
$query = "SELECT items.`name`,
snapshots.`value`,
snapshots.`taken_at`,
FROM snapshots
INNER JOIN (
SELECT MAX(id) AS id, item_id
FROM snapshots
WHERE `taken_at` > ?
AND snapshots.`cohort_id` $sqlCohortString
GROUP BY item_id
) latest
ON latest.`id` = snapshots.`id`
INNER JOIN items
ON items.`id` = snapshots.`item_id`
ORDER by media_items.`slug` ASC
";
$chartData = DB::select($query, $params);
My question is: does Laravel have a way to detect null values and replace ? more intelligently?
PS: The SQL is for a chart, so I need the single highest snapshot value for each item.
You can use ->when to create a conditional where clause:
$data = DB::table('table')
->when($cohortId === null, function ($query) {
return $query->whereNull('cohort_id');
}, function ($query) use ($cohortId) {
// the "use" keyword provides access to "outer" variables
return $query->where('cohort_id', '=', $cohortId);
})
->where('taken_at', '>', $someDate)
->toSql();

How can I concat 2 columns with eachother without using Raw Sql Concat

I am working on a new project in Laravel 8 where I am allowed to use as little RAW SQL as possible.
For a number of situations I have to Concat 2 columns together (as it is shown below) and that is actually easy to do with Raw Sql. But I am not allowed to use Raw Sql for that.
BoekhoudingVerdichting::select('boekhouding_verdichting.id', DB::raw("CONCAT(boekhouding_verdichting.verdichtingnr,' - ',verdichting) AS verdichting, CONCAT(boekhouding_hoofdverdichting.hoofdverdichtingnr,' - ',hoofdverdichting) AS hoofdverdichting"))
->join('boekhouding_hoofdverdichting', function ($q) {
$q->on('boekhouding_hoofdverdichting.id', 'boekhouding_verdichting.id_hoofdverdichting');
})
->join('boekhouding_grootboek', function ($q) {
$q->on('boekhouding_grootboek.id_verdichting', 'boekhouding_verdichting.id');
})
->groupBy('boekhouding_verdichting.id')
->orderBy('boekhouding_verdichting.verdichtingnr')
->orderBy('boekhouding_verdichting.verdichting')
->get();
I got a tip that I first have to get the data from the database as a Collection (as it is shown below) and then put the Collection through a map-function and in the map-function I can Concat the columns and return them! I searched the internet but I couldn't find any soloution.
Maybe you have another solution?
I hope you can help me with it.
BoekhoudingVerdichting::select('boekhouding_verdichting.id', 'boekhouding_verdichting.verdichtingnr', 'verdichting', 'boekhouding_hoofdverdichting.hoofdverdichtingnr', 'hoofdverdichting')
->join('boekhouding_hoofdverdichting', function ($q) {
$q->on('boekhouding_hoofdverdichting.id', 'boekhouding_verdichting.id_hoofdverdichting');
})
->join('boekhouding_grootboek', function ($q) {
$q->on('boekhouding_grootboek.id_verdichting', 'boekhouding_verdichting.id');
})
->groupBy('boekhouding_verdichting.id')
->orderBy('boekhouding_verdichting.verdichtingnr')
->orderBy('boekhouding_verdichting.verdichting')
->get();
Solved the problem!
$collection = BoekhoudingVerdichting::select('boekhouding_verdichting.id', 'boekhouding_verdichting.verdichtingnr', 'verdichting', 'boekhouding_hoofdverdichting.hoofdverdichtingnr', 'hoofdverdichting')
->join('boekhouding_hoofdverdichting', function ($q) {
$q->on('boekhouding_hoofdverdichting.id', 'boekhouding_verdichting.id_hoofdverdichting');
})
->join('boekhouding_grootboek', function ($q) {
$q->on('boekhouding_grootboek.id_verdichting', 'boekhouding_verdichting.id');
})
->groupBy('boekhouding_verdichting.id')
->orderBy('boekhouding_verdichting.verdichtingnr')
->orderBy('boekhouding_verdichting.verdichting')
->get();
$newCollection = $collection->map(function ($item, $key) {
$item['verdichting'] = $item['verdichtingnr'] . ' - ' . $item['verdichting'];
$item['hoofdverdichting'] = $item['hoofdverdichtingnr'] . ' - ' . $item['hoofdverdichting'];
return $item;
});
$solved = $newCollection->all();

whereHas is not working on NULL value

in laravel 5.5 whereHas() is not working on where value is NULL. my relationship with other model is one to many and and i want to pick the values from the model where value is equal to NULL . But instead of returning the specific values its returning all the value in result
plans = Plan::with('objectives')->with('objectives.keyResults')
->whereHas('objectives', function($query) {
$query->whereNull('entity_id');
$query->whereNull('quarter_id');
})->where('companyKey', Auth::user()->companyKey)->get();
You have to specify the constraint twice:
$plans = Plan::with(['objectives' => function($query) {
$query->whereNull('entity_id');
$query->whereNull('quarter_id');
}, 'objectives.keyResults'])
->whereHas('objectives', function($query) {
$query->whereNull('entity_id');
$query->whereNull('quarter_id');
})->where('companyKey', Auth::user()->companyKey)
->get();
No double constraints are needed, simplify it to:
$plans = Plan::whereHas('objectives', function($query) {
$query->whereNull('entity_id');
$query->whereNull('quarter_id');
})->with(['objectives'])
->where('companyKey', Auth::user()->companyKey)
->get();

How to select items by providing where clause in pivot

This is my code looks like right now :
$result = Category::with(array(
"getProducts",
"getProducts.getBrand",
"getProducts.getImages",
"getProducts.getDetail",
"getProducts.getTax",
"getProducts.getDiscount",
"getProducts.getAttributes" => function($query) use($_temp){
if($_temp != null){
$query->where_in('attributes.id',$_temp);
}
},
"getSlideshow",
"getSlideshow.getItems",
"getAttributeListing",
"getAttributeListing.getAttributes",
"getAttributeListing.getAttributes.productSpecific"
))
->where('id','=', $category_id)
->first();
Yet, It only filters the getProducts.getAttributes items not the 'getProducts' itself. Is there a way that I can get the Products by attributes?
Note: I am using Laravel 3