find values of json array using postgresql query - json

This is my JSON value
"order": {
"items": [{
"amount": 30000,
"product_name": "product A",
"quantity": 3,
}, {
"amount": 1000,
"product_name": "product B",
"quantity": 1,
}],
"currency": "USD"
}
I want get values of amount from the array using mysql queries. I tried select json_extract_path_text('order','items') but it fetches whole value
[{
"amount": 30000,
"product_name": "product A",
"quantity": 3,
}, {
"amount": 1000,
"product_name": "product B",
"quantity": 1,
}]
Can you help me?

You can use json_array_elements() function:
select
(value->>'amount')::int as amount
from json_array_elements(
'{"order":
{ "items": [
{"amount": 30000,"product_name": "product A", "quantity": 3},
{"amount": 1000,"product_name": "product B","quantity": 1}
],
"currency": "USD"}
}'::json->'order'->'items'
)

Related

N1ql SUM on UNNEST Array

N1ql SUM on UNNEST Array
I have a single bucket (Couchbase Community edition 6.5) consisting of the following documents:
FishingDoc
{
"boatIds": ["boatId_1","boatId_2","boatId_3"],
"areaIds": ["areaId_1","areaId_2","areaId_3"],
"total": 10,
"date": "2021-05-13T00:00:00Z",
"type": "fishing"
},
{
"boatIds": ["boatId_1","boatId_3"],
"areaIds": ["areaId_2","areaId_3"],
"total": 25,
"date": "2021-05-15T00:00:00Z",
"type": "fishing"
}
RiverDoc
{
"_id": "areaId_1",
"size": 5,
"type": "river"
},
{
"_id": "areaId_1",
"size": 10,
"type": "river"
},
{
"_id": "areaId_1",
"size": 15,
"type": "river"
}
BoatDoc
{
"_id": "areaId_1",
"name": "Small Boat",
"type": "boat"
},
{
"_id": "areaId_1",
"name": "Medium Boat",
"type": "boat"
},
{
"_id": "areaId_1",
"name": "Large Boat",
"type": "boat"
}
I need a query where I can get all of the fishing docs broken up per river and per boat. I got this working using the UNNEST operator in the following query:
SELECT river.size,
boat.name,
fishing.total
FROM bucket_name fishing
UNNEST fishing.riverIds AS river
UNNEST fishing.boatIds AS boat
WHERE fishing.type = "fishing"
But the problem in this query is that the total value in the above query is the total for the entire fishing object.
I need to get the total, relative to the size of the unnested river. So I need to join in and sum the total of all the rivers for the fishing object and get the specific river's size relative to the total.
Here is the select statement I have in mind but I have no idea on how to actually write the correct query:
SELECT river.size,
boat.name,
river.size/SUM( fishing.riverIds[0].size, fishing.riverIds[1].size, fishing.riverIds[2].size ) * fishing.total
FROM bucket_name fishing
UNNEST fishing.riverIds AS river
UNNEST fishing.boatIds AS boat
WHERE fishing.type = "fishing"
INSERT INTO default VALUES ("f01", { "boatIds": ["boatId_1","boatId_2","boatId_3"], "areaIds": ["areaId_1","areaId_2","areaId_3"], "total": 10, "date": "2021-05-13T00:00:00Z", "type": "fishing" });
INSERT INTO default VALUES ("f02", { "boatIds": ["boatId_1","boatId_3"], "areaIds": ["areaId_2","areaId_3"], "total": 25, "date": "2021-05-15T00:00:00Z", "type": "fishing" });
INSERT INTO default VALUES ("areaId_1", { "_id": "areaId_1", "size": 5, "type": "river" });
INSERT INTO default VALUES ("areaId_2", { "_id": "areaId_2", "size": 10, "type": "river" });
INSERT INTO default VALUES ("areaId_3", { "_id": "areaId_3", "size": 15, "type": "river" });
INSERT INTO default VALUES ("boatId_1", { "_id": "boatId_1", "name": "Small Boat", "type": "boat" });
INSERT INTO default VALUES ("boatId_2", { "_id": "boatId_2", "name": "Medium Boat", "type": "boat" });
INSERT INTO default VALUES ("boatId_3", { "_id": "boatId_3", "name": "Large Boat", "type": "boat" });
SELECT ARRAY {"size": f.river.[v], "name": f.boat.[f.boatIds[pos]], "total": f.total*f.river.[v]/ARRAY_SUM(OBJECT_VALUES(f.river))}
FOR pos:v IN f.areaIds END AS distribution
FROM (SELECT d.*,
OBJECT v._id:v.size FOR v IN (SELECT r._id, r.size FROM default AS r USE KEYS d.areaIds) END AS river,
OBJECT v._id:v.name FOR v IN (SELECT b._id, b.name FROM default AS b USE KEYS d.boatIds) END AS boat
FROM default AS d
WHERE d.type = "fishing") AS f;
{
"requestID": "fbe127b4-2ebb-4b01-a8a1-0bfe5310ed42",
"signature": {
"distribution": "array"
},
"results": [
{
"distribution": [
{
"name": "Small Boat",
"size": 5,
"total": 1.6666666666666667
},
{
"name": "Medium Boat",
"size": 10,
"total": 3.3333333333333335
},
{
"name": "Large Boat",
"size": 15,
"total": 5
}
]
},
{
"distribution": [
{
"name": "Small Boat",
"size": 10,
"total": 10
},
{
"name": "Large Boat",
"size": 15,
"total": 15
}
]
}
],
"status": "success",
"metrics": {
"elapsedTime": "6.946602ms",
"executionTime": "6.881065ms",
"resultCount": 2,
"resultSize": 730,
"serviceLoad": 2
}
}
OR
SELECT river AS SectionSize,
f.total*(river/ARRAY_SUM(f.sections)) AS total,
f.boats[UNNEST_POS(river)] AS name
FROM (SELECT d.total,
(SELECT RAW r.size FROM default AS r USE KEYS d.areaIds) AS sections,
(SELECT RAW b.name FROM default AS b USE KEYS d.boatIds) AS boats
FROM default AS d
WHERE d.type = "fishing") AS f
UNNEST f.sections AS river;
{
"results": [
{
"SectionSize": 5,
"name": "Small Boat",
"total": 1.6666666666666665
},
{
"SectionSize": 10,
"name": "Medium Boat",
"total": 3.333333333333333
},
{
"SectionSize": 15,
"name": "Large Boat",
"total": 5
},
{
"SectionSize": 10,
"name": "Small Boat",
"total": 10
},
{
"SectionSize": 15,
"name": "Large Boat",
"total": 15
}
]
}

Having problems entering JSON into MySQL database

I am trying to develop a system to handle data from a third party site. I will enter their data in my MySQL DB. Part of their data is a JSON string. I am new to JSON in MySQL. I have read and watched a tutorial on how to query JSON. I have done so successfully with JSON strings that I have entered. The problem is I cannot get their string to insert into my table. I get an error that says,"#3140 - Invalid JSON text: "The document root must not follow by other values." at position 11 in value for column 'ordered_shed.items'. Below is the JSON I received from the company. I have looked at it and cannot figure out what the problem is. I am using PHPMyAdmin to insert the code. The structure is.
id int(11) AUTO_INCREMENT
items JSON
"lineItems":[
{ "description": "details-item-size",
"productKey": "size",
"quantity": 1
},
{ "description": "details-item-style",
"model": "",
"price": 2229,
"productKey": "style",
"quantity": 1,
"value": ""
},
{ "description": "details-item-flooring",
"price": 0,
"productCategory": "flooring-interior",
"quantity": 1
},
{ "description": "details-item-floor-joist",
"productCategory": "flooring-interior",
"quantity": 1
},
{ "description": "details-item-roof-overhang",
"productKey": "RoofOverhang",
"quantity": 1
},
{ "description": "details-item-sidewall-height",
"productKey": "wall-height",
"quantity": 1
},
{ "description": "standard",
"productCategory": "structure",
"quantity": 1
},
{ "description": "Pressure Treated Skids",
"productCategory": "structure",
"quantity": 1
},
{ "description": "details-item-loft",
"productCategory": "flooring-interior",
"quantity": 1
},
{ "description": "details-item-roof-material",
"productKey": "roof-material",
"quantity": 1
},
{ "description": "details-item-siding-color",
"quantity": 1,
"productKey": "siding-color"
},
{ "description": "details-item-siding",
"productKey": "siding",
"quantity": 1
},
{ "description": "details-item-roof-color",
"quantity": 1,
"productKey": "roof-color"
},
{ "description": "details-item-trim-color",
"quantity": 1,
"productKey": "trim-color"
}]
Any help would be greatly appreciated.
The JSON you've provided is not valid. You can always check here.
I think you just need your JSON to look like this:
{
"lineItems": [{
"description": "details-item-size",
"productKey": "size",
"quantity": 1
},
{
"description": "details-item-style",
"model": "",
"price": 2229,
"productKey": "style",
"quantity": 1,
"value": ""
},
{
"description": "details-item-flooring",
"price": 0,
"productCategory": "flooring-interior",
"quantity": 1
},
{
"description": "details-item-floor-joist",
"productCategory": "flooring-interior",
"quantity": 1
},
{
"description": "details-item-roof-overhang",
"productKey": "RoofOverhang",
"quantity": 1
},
{
"description": "details-item-sidewall-height",
"productKey": "wall-height",
"quantity": 1
},
{
"description": "standard",
"productCategory": "structure",
"quantity": 1
},
{
"description": "Pressure Treated Skids",
"productCategory": "structure",
"quantity": 1
},
{
"description": "details-item-loft",
"productCategory": "flooring-interior",
"quantity": 1
},
{
"description": "details-item-roof-material",
"productKey": "roof-material",
"quantity": 1
},
{
"description": "details-item-siding-color",
"quantity": 1,
"productKey": "siding-color"
},
{
"description": "details-item-siding",
"productKey": "siding",
"quantity": 1
},
{
"description": "details-item-roof-color",
"quantity": 1,
"productKey": "roof-color"
},
{
"description": "details-item-trim-color",
"quantity": 1,
"productKey": "trim-color"
}
]
}
You can use
SELECT json_valid(<jscol>) as "isValid?"
to check whether json column is valid. If returns 1 then it's valid. Invalid if it returns 0 (zero), and you can insert like this :
insert into tab(items)
select case when json_valid(<jscol>)=1 then
<jscol>
end;
Demo

Remove json object from array of objects in mysql

I have a column userinventory in mysql table with below data and I want to remove one of json object where "sellFlag":"y" and "product_id":"1"
[{
"price": "250",
"category": "Furniture",
"sellFlag": "y",
"assetLink": "Furniture/Table",
"product_id": "1"
},
{
"price": "175",
"category": "Furniture",
"assetLink": "Furniture/IkeaStockholmCoffeeTableBlack",
"product_id": "31"
},
{
"price": "300",
"category": "Furniture",
"assetLink": "Furniture/ZanottaDamaSofaMultiseater",
"product_id": "29"
},
{
"price": "200",
"category": "Furniture",
"assetLink": "Furniture/RoundTable",
"product_id": "9"
}]
I have tried select JSON_SEARCH(userInventory,'all','y', NULL,'$[*].sellFlag') as uInvent FROM user_information WHERE user_id=50 its giving result "$[27].sellFlag" but I need to add condition for product_id too
After successful removal, below result is required.
[{
"price": "175",
"category": "Furniture",
"assetLink": "Furniture/IkeaStockholmCoffeeTableBlack",
"product_id": "31"
},
{
"price": "300",
"category": "Furniture",
"assetLink": "Furniture/ZanottaDamaSofaMultiseater",
"product_id": "29"
},
{
"price": "200",
"category": "Furniture",
"assetLink": "Furniture/RoundTable",
"product_id": "9"
}]
You can convert it to collection of objects and then loop them in foreach
and test any conditions and remove any object
and in the end convert it again to json

Angular 7 - How to display array inside of an object in HTML

I am trying to display array inside of an object in HTML. My sample JSON is like below...
I would like to display Product > ProductCategoryRelations > Category.Name in a string comma separeted like "Category 1, Category 2"
[
{
"Id": 2,
"Name": "Product 1",
"ProductCategoryRelations": [
{
"Id": 3,
"ProductId": 2,
"CategoryId": 2,
"Active": true,
"Category": {
"Id": 2,
"ParentId": 1,
"Name": "Category 1"
}
},
{
"Id": 4,
"ProductId": 2,
"CategoryId": 2,
"Active": true,
"Category": {
"Id": 2,
"ParentId": 1,
"Name": "Category 2"
}
}
],
How can I put all categories name in a string comma seperated?
What I have so fas is like below but it doesnt worrk
<dd class="col-sm-9" *ngFor="let category of product.ProductCategoryRelations">
<span>{{category.Name}}</span>
</dd>
In javascript, you would need this:
product.ProductCategoryRelations
.map(r => r.Category.Name)
.join(',')
to put it in context:
let product = {
"Id": 2,
"Name": "Product 1",
"ProductCategoryRelations": [
{
"Id": 3,
"ProductId": 2,
"CategoryId": 2,
"Active": true,
"Category": {
"Id": 2,
"ParentId": 1,
"Name": "Category 1"
}
},
{
"Id": 4,
"ProductId": 2,
"CategoryId": 2,
"Active": true,
"Category": {
"Id": 2,
"ParentId": 1,
"Name": "Category 2"
}
}
],
};
console.log(
product.ProductCategoryRelations
.map(r => r.Category.Name)
.join(',')
);
Now you can use .join(',') in Angular template syntax, but you cannot use the .map() bit. So I suspect the easiest way would be to add a utility function to your component that does this for you:
getCategoryNames(product) {
return product.ProductCategoryRelations.map(r => r.Category.Name);
}
and then do it in the template like this:
{{getCategoryNames(product).join(',')}}
If you need to do the same thing in multiple places in your app across multiple components, then I would recommend writing your own custom pipe.

Export mysql data to JSON in a nested and recursivelty way starting from a table?

I have seen several examples to export MySQL tables to JSON, however such examples export data in an aggregated way. For example, take a database where you have two tables "Invoice head" and "Invoice details". "Invoice details" is a child of "Invoice head".The data in JSON is usually represented like:
{
"invoice_head": [
{
"number": 1,
"cliente": "Carlos",
"date": "2016-12-12"
},
{
"number": 2,
"cliente": "Fernando",
"date": "2017-01-01"
}
],
"invoice_details": [
{
"headnumber": 1,
"lineno": 1,
"product": "Shoes",
"quantity": 2
},
{
"headnumber": 1,
"lineno": 2,
"product": "Socks",
"quantity": 1
},
{
"headnumber": 2,
"lineno": 1,
"product": "Laptop",
"quantity": 1
}
],
}
I need to export data in a nested way:
{
"invice_head": [
{
"number": 1,
"cliente": "Carlos",
"date": "2016-12-12",
"invice_details": [
{
"headnumber": 1,
"lineno": 1,
"product": "Shoes",
"quantity": 2
},
{
"headnumber": 1,
"lineno": 2,
"product": "Socks",
"quantity": 1
}
]
},
{
"number": 2,
"cliente": "Fernando",
"date": "2017-01-01"
"invice_details": [
{
"headnumber": 2,
"lineno": 1,
"product": "Laptop",
"quantity": 1
}
]
}
]
}
For this I guess one needs to start in a table and recursively go through its childs for each record.
Does anybody knows if there is anything that does it? I don't want to reinvent the wheel.