I have following JSON code in my database table
[
{
"indentifier": "category",
"name": "XXXXXXX",
"products": [
{
"indentifier": "childproduct",
"name": "XXXX",
"price": 15,
"sku": "+0094",
"factorynumber": "156670",
"unit": "50 Stk/Pck",
"kp": "50",
"discountCode": "V",
"from": "2020-01-01",
"to": "2099-01-01"
},
...
]
},
{
"indentifier": "category",
"name": "XXXXXXX",
"products": [
{
"indentifier": "childproduct",
"name": "XXXX",
"price": 29,
"sku": "+0104",
"factorynumber": "156680",
"unit": "50 Stk/Pck",
"kp": "50",
"discountCode": "V",
"from": "2020-01-01",
"to": "2099-01-01"
},
....
]
}
]
Now how I can implement for searching the sku in this JSON in "when" keyword? My following code is here:
$date = now()->toDateString();
if ($request->keyword != "") {
$keyword = $request->keyword;
} else {
$keyword = false;
}
$products = Product::whereJsonContains('catalogs', intval($request->catalog))
->whereDate('from', '<=', $date)
->whereDate('to', '>', $date)
->orderBy('category', 'ASC')
->orderBy('sort', 'ASC')
->where('active', 1)
})
->when(
$keyword,
function ($query, $keyword) use ($category) {
$query->where('sku', 'like', '%' . $keyword)
->orWhere('factorynumber', 'like', $keyword)
->orWhere('name', 'like', '%' . $keyword . '%')
->orWhereJsonContains('childs', ['products->sku' => $keyword])
->where('active', 1)
});
}
)->get();
The line with
->orWhereJsonContains('childs', ['products->sku' => $keyword])
will not work... what is the right syntax for the query? At moment there are 0 results if search for child sku field.
Thanks for helping
orWhereJsonContains() doesn't exist in Laravel, but whereJsonContains(), and it works with arrays and not the associative arrays. Also you have to make sure the data from json goes as the first argument, not the second like this:
whereJsonContains('table_column_name_with_json_in_it->json_value_key',$requiredValue)
In that case this query of yours:
->orWhereJsonContains('childs', ['products->sku' => $keyword])
Should be something like this:
->WhereJsonContains('product->sku', $sku)
Related
Here I want to make the array inside "property" to an object where the key of the object will be the value of 'key_name' column of product_property table
[{
"sort_order": 1,
"name": "Samosas",
"visible": 1,
"description": null,
"property": [
{
"product_uuid": "95be9cf4-7121-492b-8725-762e6353ac51",
"key_name": "categories",
"key_value": "Starter"
},
{
"product_uuid": "95be9cf4-7121-492b-8725-762e6353ac51",
"key_name": "print_order",
"key_value": "1"
}
]
}]
This is what I want
[{
"sort_order": 1,
"name": "Samosas",
"visible": 1,
"description": null,
"property": {
"categories": "Starter",
"print_order": "1"
}
}]
I tried with Product::with('property')->get() and it results the first array.
Is there any Eloquent way to do that or raw sql or Query Builder?
Looping throw the result and make that object is possible but here i want something from SQL end
$products = Product::with('property')->get();
foreach ($products as $product) {
$array = [];
foreach ($product->property as $property) {
$array[$property['key_name']] = $property['key_value'];
}
$product->properties = $array;
}
This looping giving me the results but its from php end
public function property(){
return $this->hasMany(ProductProperty::class, 'product_uuid', 'uuid');
}
The Product model
Product table
"sort_order",
"name",
"visible",
"description",
Product Property table
"product_uuid",
"key_name",
"key_value"
Thanks in advance
$products = Product::with('property')->get();
foreach ($products as $product) {
$array = [];
foreach ($product->property as $property) {
$array[$property['key_name']] = $property['key_value'];
}
$product->properties = (object) $array;
}
Add object. It will convert this to a std object.
I have a table name leave_requests like this
[leave request table][1]
[1]: https://i.stack.imgur.com/B7VvC.png
from above table I want to get total leaves between two time like (From 2021-12-02 to 2021-12-07) only when I have status "Approved", I have done this so far
LeaveRequest
::where("start_date", ">=", $request->from)
->where("end_date", "<=", $request->to)
->where("status", "approved")
->get()
as from above code I am matching two date conditions, this is the output:
{
"id": 31,
"code": "1o1545",
"organization_id": 1,
"employee_id": 7,
"leave_id": 1,
"start_date": "2021-12-03",
"end_date": "2021-12-06",
"reason": "sick",
"status": "approved",
"created_at": "2021-12-01 21:01:59",
"updated_at": "2021-12-01 21:02:14",
"leave_days": 4,
"is_archived": false,
"is_inactive": true,
"is_geofencing": false,
"is_tax_exempted": false,
"full_name": "",
"current_position": null
},
{
"id": 34,
"code": "mygm39",
"organization_id": 1,
"employee_id": 7,
"leave_id": 1,
"start_date": "2021-12-04",
"end_date": "2021-12-04",
"reason": "ljk",
"status": "approved",
"created_at": "2021-12-03 09:35:59",
"updated_at": "2021-12-03 09:35:59",
"leave_days": 1,
"is_archived": false,
"is_inactive": true,
"is_geofencing": false,
"is_tax_exempted": false,
"full_name": "",
"current_position": null
},
{
"id": 35,
"code": "m1e8zy",
"organization_id": 1,
"employee_id": 7,
"leave_id": 1,
"start_date": "2021-12-07",
"end_date": "2021-12-07",
"reason": "jj",
"status": "approved",
"created_at": "2021-12-03 09:36:43",
"updated_at": "2021-12-03 09:36:43",
"leave_days": 1,
"is_archived": false,
"is_inactive": true,
"is_geofencing": false,
"is_tax_exempted": false,
"full_name": "",
"current_position": null
}
The problem is that it will not give me rows where date is present like date is starting from (2021-12-02) but it didnot give me that record plus how to count leaves from leaves column. hope I am clear and please someone help me here I am new to laravel thanks.
Try this query:
LeaveRequest
::where("start_date", ">=", $request->from)
->where("end_date", "<=", $request->to)
->where("status", "approved")
->select('leave_id', \DB::raw('count(*) as total_leaves'))
->groupBy('leave_id')
->get();
I have finally found a solution to this below is code attached for someone in future:
use App\Models\LeaveRequest;
use Carbon\CarbonPeriod;
$total_leaves = 0;
LeaveRequest
::when($request->from && $request->to, function($query) use($request) {
$query
->whereDate("leave_requests.start_date", "<=", $request->to)
->whereDate("leave_requests.end_date", ">=", $request->from);
})
->when($request->from && !$request->to, function($query) use($request) {
$query
->whereDate("leave_requests.start_date", "<=", $request->from)
->whereDate("leave_requests.end_date", ">=", $request->from);
})
->where("leave_requests.status", "approved")
->get()
->map(function($leave_request) use(&$total_leaves, $request) {
// echo $leave_request->start_date . " " . $leave_request->end_date . "<br/>";
if(!$request->to && Carbon::parse($request->from)->betweenIncluded($leave_request->start_date, $leave_request->end_date)) {
$total_leaves++;
} else {
// echo $leave_request->start_date . " " . $leave_request->end_date . "<br/>";
$DB_periods = CarbonPeriod::create($leave_request->start_date, $leave_request->end_date);
$REQUEST_periods = CarbonPeriod::create($request->from, $request->to);
foreach ($DB_periods as $period1) {
// echo "DB-> " . $period1->format('Y-m-d') . "<br>";
foreach($REQUEST_periods as $period2) {
// echo "Request-> " . $period2->format('Y-m-d') . "<br>";
if($period1 == $period2) {
$total_leaves++;
}
}
}
}
});
return "Total Leaves: " . $total_leaves;
As I have told I am new to programming and make this solution after many hours of hardships so point is this code is lengthy and maybe not such good practice, so if any pro can minimize it thanks.
I am Using Laravel
below mentioned is one of my db table columns
:
{ "body": { "age": { "dob": "1960-01-28", "age_in_years": 60, "dob_computed": false }, "gender": "female", "address": { "street": "No.341,KC De silvapura", "country": "LK", "locality": "Thimbirigaskatuwa", "postcode": "N/A" }, "comment": "", "id_type": "NID", "id_number": 869000000000, "last_name": "Dayawansa", "member_id": "", "first_name": "jj", "preferred_name": "", "contact_details": { "email": "", "phone_number_alternate": "", "phone_number_preferred": 716900761 }, "consent_obtained": true, "alternate_contacts_details": { "name": "", "email": "", "phone_alternate": "", "phone_preferred": "" } }, "meta": { "end_time": "2019-09-06", "start_time": "2019-09-06", "registered_by": "24f57630-a102-11ea-a415-23a06eeb8904" } }
my code is
My controller
:
$start_date = $request->has('startDate') ? $request->get('startDate') : Carbon::now()->subDays(30)->format('m/d/Y');
$end_date = $request->has('endDate') ? Carbon::parse($request->get('endDate'))->addDays(1)->format('m/d/Y') : Carbon::now()->addDays(1)->format('m/d/Y');
if i use created at it works
$participants = Participant::Where('created_at', '>=', $start_date)
->where('created_at', '<=', $end_date);
if is use start_time which is inside a array it returns empty
$participants = Participant::Where('data->meta->start_time', '>=', $start_date)
->where('data->meta->start_time', '<=', $end_date);
this isn't working
any suggestion where am i wrong ?
I have tested your code and I think you should change your date format and you should receive startDate and endDate in the same format form request as your column value has. Like, you have the start_time something like that "start_time": "2019-09-06" in your DB. So, use the same date format when you will compare it.
Test your code in this way.
$start_date = Carbon::parse('2019-09-06')->format('Y-m-d');
$end_date = Carbon::parse('2019-09-10')->format('Y-m-d');
You will get a response but if you use the below format then you will not receive any response.
$start_date = Carbon::parse('2019-09-06')->format('m/d/Y');
$end_date = Carbon::parse('2019-09-10')->format('m/d/Y');
Your query is fine. Just make sure that your json column name is data.
$participants = Participant::where('data->meta->start_time', '>=', $start_date)
->where('data->meta->start_time', '<=', $end_date)->get();
Use whereBetween method of elocuent:
$start_date = $request->has('startDate') ? $request->get('startDate') : Carbon::now()->subDays(30)->format('m/d/Y');
$end_date = $request->has('endDate') ? Carbon::parse($request->get('endDate'))->addDays(1)->format('m/d/Y') : Carbon::now()->addDays(1)->format('m/d/Y');
$participants = Participant::whereBetween('start_time', [$start_date , $end_date])->get(); // or ->first() ur choice.
to more details
How to GROUP BY multiple levels in Laravel. I've tried this code.
I've also used toArray() then array_values(), but same result as using values()
EDIT: Sorry, I wrote value() instead of values()
When using values(), product_name not showing.
// Controller
$products = DB::table('product_registrations')
// ->select(['product_name', 'color'])
->join('colors', 'colors.id', '=', 'product_registrations.color_id')
->join('sizes', 'sizes.id', '=', 'product_registrations.size_id')
->join('products', 'products.id', '=', 'product_registrations.product_id')
->get()
->groupBy(['product_name', 'color']);
// ->values(); // I've used values(), it worked but first level groupBy name missing
return response()->json(['products' => $products]);
---
I want something like:
products: [
product1: [
color1: {},
color2: {}
]
]
Without values()
{
"products": {
"light blue dress": {
"Ягаан": [
{
"id": 1,
"product_id": 1,
"color_id": 1,
"size_id": 6,
"color": "Ягаан",
"product_name": "light blue dress",
}
],
},
}
}
With values()
{
"products": [
{
"Ягаан": [
{
"id": 1,
"product_id": 1,
"color_id": 1,
"size_id": 6,
"color": "Ягаан",
"product_name": "light blue dress",
}
],
}
]
}
Try this one. I also have problem on this last week but I manage to get through.
$products::latest()->get();
$products = products->groupBy(function($product) {
return $product->name;
});
$products = products->map(function($product) {
return $product->groupBy(function($prod) {
return $prod->color;
});
});
return $products;
You can also optimize this method by using array_only this method is only for laravel
I have a perl script which does some query and return response in JSON format. But the return JSON is only array of values.
This is Perl Script
my $sql_query = "SELECT * from table_categories";
my $statement = $db_handle->prepare ($sql_query) or die "Couldn't prepare query '$sql_query': $DBI::errstr\n";
$statement->execute() or die "SQL Error: $DBI::errstr\n";
my #loop_data = ();
while (my #data = $statement->fetchrow_array())
{
push(#loop_data, #data);
}
my $json;
$json->{"entries"} = \#loop_data;
my $json_text = to_json($json);
print $json_text;
and response is like this
{
"entries": [
[
"1",
"Salt and Sugar",
"/images/salt_sugar.png",
"7"
],
[
"2",
"Tea and Coffee",
"/images/tea_and_coffee.png",
"6"
],
[
"3",
"Spice and Pickles",
"/images/categories/spice_pickles.png",
"7"
],
[
"4",
"Pooja Needs",
"/images/categories/pooja-needs.png",
"9"
],
[
"5",
"Dry Fruits",
"/images/categories/dry_fruits.png",
"7"
]
]
}
But I want the response like this:
{
"entries": [
[
"id": "1",
"name": "Salt and Sugar",
"image": "/images/salt_sugar.png",
"rank": "7"
],
[
"id": "2",
"name": "Tea and Coffee",
"image": "/images/tea_and_coffee.png",
"rank": "6"
]
]
}
How to achieve that?
What changes i need to do in PERL script?
Please help.
If you specifically don't have need to loop over every row, I'd prefer to use selectall_arrayref with slicing:
my $json;
my $sql_query = "SELECT * FROM table_categories";
$json->{entries} = $db_handle->selectall_arrayref( $sql_query, {Slice => {} } );
my $json_text = to_json($json);
print $json_text;
So you get keys too and code is more compact and clear.
You can use fetchrow_hashref instead of fetchrow_array to receive a hashref where the column names are used for the property names using the code below.
my #loop_data = ();
while (my $hashref = $statement->fetchrow_hashref())
{
push(#loop_data,$hashref);
}
More information: https://metacpan.org/pod/DBI#fetchrow_hashref