Laravel 9 how to best query JSON object in JSON column? - php

I've got a basic app up and running in the latest version of Laravel 9 that's utilising JSON columns for storing certain bits of data. I have a job_type_rates column on my Client model/table, where some have a value similar to:
[
{
"job_type": "8",
"pay_rate": "15.45",
"charge_rate": "18.45",
"awr_pay_rate": "21.33",
"awr_charge_rate": "26.77"
}
]
What I would like to do is select all clients that have a job_type of 8. I've tried to do Client::whereJsonContains('job_type_rates->job_type', "8")->get() but no results are returned, however that code would work if I didn't have an object in the column.
One way I can get around this is to create a pivot table and go down that route, but I was wondering if anyone had come up against this before and perhaps used a closure or similar?

Based on the comment by #RiggsFolly I tried this code:
Client::whereJsonContains('job_type_rates', ["job_type" => "8"])->get()
And it works, it returns the expected results. As far as I'm aware this isn't in the Laravel docs (which mostly show single value examples).
I think it's still better to extract this out into a pivot table or similar, but I hope this helps someone!

Related

Can't get result from where condition with variables in laravel

this is how i'm trying to get the type of certificate with where condition , but still recieve
nothing from this query:
$res= student::find($student, ['typecertificate']);
$k = certificate::select('id-cer')->where('name-cer','=',$res)->get();
return $k;
Based on your comments, I'm assuming you want to retrieve the field certificateType from the latest record that was inserted in the students table.
You can achieve that without a where clause, by directly using the Eloquent Builder to retrieve only that specific field like this:
Student::latest()->first('certificateType');
But this would give you an Eloquent Collection with one element. If you just want the value (not wrapped in a collection), you can simply retrieve the latest student and get the corresponding field directly:
$certificateType = Student::latest()->first()->certificateType;
I could explain more, but your question is vague and your database schema isn't clear either, so I'd need more information on that as well as what you intend to achieve.
In any case, Laravel's documentation is often a big help: https://laravel.com/docs/9.x/eloquent#retrieving-single-models

How to query whereIn inside json column in laravel 5.3?

I have been working with a laravel 5.3 version and in a table i have a json column where i have saved average rating of a category table.
so, A product category table has a column "detail" as a json data type which saves avgRating.
I want to run a query inside that json column. And i want to filter that category with a average rating. So, from the frontend side rating comes in a parameter with a comma seperated so that category can be filtered with multiple ratings.
$productCategory = ProductCategory::query();
$ratings = explode(',',$params['ratings']);
$productCategory = $productCategory->whereIn('detail->avgRating',$ratings)->get();
I want to achieve something like this.
I am using Postgres
It turns out that there was too much uncertainty at the time when the question was asked. Once the asker separated the problems and figured out that the raw query of
DB::select(DB::raw("SELECT * FROM product_categories where detail->>'avgRating' in ('2.0','4.0')"));
works in Postgres, the asker from that point onwards had a much easier time figuring out the actual solution in the where clause. I presuppose that it was
detail->>avgRating
instead of
detail->avgRating
but from the comment section that was not yet confirmed. But the moral of the story is that whenever one has an eloquent problem that might be related to the RDBMS, then it makes a lot of sense to first sort out the raw query and then, having solid knowledge about what should be generated, at that point one can switch to the Eloquent code and apply the solution there.
You should use whereJsonContains or whereRaw:
$productCategory->whereJsonContains('detail->>avgRating',$ratings)->get();
OR
$productCategory->whereRaw('JSON_CONTAINS(detail->>avgRating, ?)', $ratings)->get();

Laravel query json column array

I am trying to access specific data in a json column using a laravel controller, the DB column is called 'figuresinorder'. I want to access the "wants" key but it's not working when there are multiple values stored.
{"wants": ["1"], "trades": ["12,33,234"]} - this works
{"wants": ["1,2,3"], "trades": ["12,33,234"]} - does not work
The query in the controller is as follows:
$figures2 = customtrades::whereJsonContains('figuresinorder->wants', ['1'])->get();
Any help will be greatly received, been stuck on this for longer than I dare to admit.
MySQL & PostgreSQL support whereJsonContains() with multiple values like this way :
customtrades::whereJsonContains('figuresinorder->wants', ['1','2','3'])->get();
For more, see the documentation here

Comparing columns in laravel

Sorry in advance for inappropriate question.I am a beginner in php and laravel. Wondering where i am doing mistake in the following code fragment.
$customer_vlan = Customer::select('vlan_id')->get();
$vlans = Vlans::where(function($query) use ($customer_vlan){
$query->where('id','!=',$customer_vlan);
})->get();
I have two tables in database."Customer" table has a column 'vlan_id'. In first query i am trying to fetch used vlan_id.
For second table "Vlans", column'id' holds all possible vlan. So i am trying to find which vlan's not used.
You are trying to compare id with a collection. Then the result is all of the Vlans.
$query->where('id','!=',$customer_vlan);
I think the best way to do this is loop through $customer_vlan collection and push $customer_vlan[$i]->id to an array. Then you can use this:
$query->whereNotIn('id', $arrayOfId);

PHP & MySQL Tickers..Is this standard practice?

I currently have about 4 different database tables which output to html tables. Each of these tables uses a count query to calculate data from a 5th table.
That's no problem, but what about when I want to sort and order the data, and paginate etc (like with zend). If it were a one page table, I could probably sort an array.
My thought was, to use a ticker. But that would require a new column in all 4 tables and seems like overkill or like there could be a better way.
Sadly, I can't find much info on it (likely because I don't know what to search for).
Advice?
..and please take it easy, I'm new and learning.
Assuming youre using Zend_Db_Table_Row and that you dont need to persist any modifications you might make to these rowsets then you can just append the virtual columns to the row object and have them be accessible via array notation. So if youre doing it all in one query now just use that same query, and the column should be there.
OTOH, if youre using a Data Mapper pattern then simply adjust your hydration to look for this "virtual column" and hydrate it if it exists in the result data. Then in your getter for this property have it see if the property is null or some other negative specification, and if it is, to execute a calculation query on that single object or return the already calculated result.

Categories