How to query an object of objects in mysql json column - mysql

I have an order_summary JSON column in my orders table with the following structure
{
"total": 16.895,
"products": { // products is an object of objects instead of array of objects
"98": {
"price": "2.400",
"quantity": 2,
"sub_total": 4.8,
"product_id": 100,
"variant_id": 98
},
"395": {
"price": "3.900",
"quantity": 1,
"sub_total": 3.9,
"product_id": 401,
"variant_id": 395
},
"732": {
"price": "7.695",
"quantity": 1,
"sub_total": 7.695,
"product_id": 754,
"variant_id": 732
}
}
}
What I am trying to do,
I have to calculate the total number of items sold for a given variant_id, So I want to fetch the sum the quantity field inside the products object.
The problem
Sadly the products field is not an array of objects instead its an object of objects. With the keys being variant_id itself. So my following query is not working
SELECT sum(order_summary->"$.products.quantity") FROM orders where order_summary->"$.products.variant_id" = 98 (which returns an empty result set)
I think this is because of the presence of the keys in the products array. So how can I tackle this?
I am using Mysql 8, kindly let me know if any more information is needed.

After some trial and error and with the help of a friend, I found the following solution,
SELECT SUM(order_summary -> '$.products."98".quantity') as sum
FROM orders
WHERE JSON_CONTAINS_PATH(order_summary, 'all', '$.products."98"')

Related

How to retrieve multiple data from jsonb column in postgres?

In PostgreSQL database I have a json column called json. Data inside look like below:
{
"Version": "0.0.0.1",
"Items": [
{
"Id": "40000000-0000-0000-0000-000000141146",
"Name": "apple",
"Score": 64,
"Value": 1430000
},
{
"Id": "40000000-0000-0000-0000-000000141147",
"Name": "grapefruit",
"Score": 58,
"Value": 1190000
},
{
"Id": "40000000-0000-0000-0000-000000141148",
"Name": "mango",
"Score": 41,
"Value": 170000
}
]
}
What I would like to do is retrieving all Score data from Items elements.
I was trying to use SQL code:
select
substring(json ->> 'Items' from '"Score": (\d*),') as score
from vegetables;
However that returns just the score from first element instead of 3. I was trying to use '\g' flag which supposed to find all results globally, but the code was not working.
Could anyone advise how to do that properly? Thanks in advance!
Considering that the data type of json field is jsonb then no need to use substring or regex, simply lateral join with jsonb_array_elements will do the required things for you. Try below query.
select x->>'Score' "Score" from vegetables
cross join lateral jsonb_array_elements(json->'Items') x
DEMO

Query All Elements in Nested JSON Array PostrgreSQL

I am trying to create a query in SQL to retrieve DNS answer information so that I can visualize it in Grafana with the add of TimescaleDB. Right now, I am struggling to get postgres to query more than one element at a time. The structure of my JSON that I am trying to query looks like this:
{
"Z": 0,
"AA": 0,
"ID": 56559,
"QR": 1,
"RA": 1,
"RD": 1,
"TC": 0,
"RCode": 0,
"OpCode": 0,
"answer": [
{
"ttl": 19046,
"name": "i.stack.imgur.com",
"type": 5,
"class": 1,
"rdata": "i.stack.imgur.com.cdn.cloudflare.net"
},
{
"ttl": 220,
"name": "i.stack.imgur.com.cdn.cloudflare.net",
"type": 1,
"class": 1,
"rdata": "104.16.30.34"
},
{
"ttl": 220,
"name": "i.stack.imgur.com.cdn.cloudflare.net",
"type": 1,
"class": 1,
"rdata": "104.16.31.34"
},
{
"ttl": 220,
"name": "i.stack.imgur.com.cdn.cloudflare.net",
"type": 1,
"class": 1,
"rdata": "104.16.0.35"
}
],
"ANCount": 13,
"ARCount": 0,
"QDCount": 1,
"question": [
{
"name": "i.stack.imgur.com",
"qtype": 1,
"qclass": 1
}
]
}
There can be any number of answers, including zero, so I would like to figure out a way to query all answers. For example, I am trying to retrieve the ttl field from every index answer, and I can query a specific index, but have trouble querying all occurrences.
This works for querying a single index:
SELECT (data->'answer'->>0)::json->'ttl'
FROM dns;
When I looked around, I found this as a potential solution for querying all indices within the array, but it did not seem to work and told me "cannot extract elements from a scalar":
SELECT answer->>'ttl' ttl
FROM dns, jsonb_array_elements(data->'answer') answer, jsonb_array_elements(answer->'ttl') ttl
Using jsonb_array_elements() will give you a row for every object in the answer array. You can then dereference that object:
select a.obj->>'ttl' as ttl, a.obj->>'name' as name, a.obj->>'rdata' as rdata
from dns d
cross join lateral jsonb_array_elements(data->'answer') as a(obj)

Select value from array of objects Cosmos DB

I have the following json
{
"car-id": "54-38ncv",
"cars": [
{
"name": "Ferrari",
"horse-powers": 400
},
{
"name": "BMW",
"horse-powers": 200
},
{
"name": "Audi",
"horse-powers": 145
}]
}
the id is custom set by me. Imagine that there are hundreds other documents in my azure cosmos db collection. I want to create query that selects the first document that has a car in the cars that is named etc. "Ferrari". I know that they are maybe a dublicates, but is want the first one. Is there a quarry for this.
You can do this,
SELECT TOP 1 FROM c JOIN cc IN c.cars WHERE cc.name IN ("Ferrari")

Select Objects from Array of Objects that match a property in MYSQL JSON

I have a table with 1 JSON type column city in a MySQL database that stores a JSON array of city objects with following structure:
{
"cities": [
{
"id": 1,
"name": "Mumbai",
"countryID": "9"
},
{
"id": 2,
"name": "New Delhi",
"countryID": "9"
},
{
"id": 3,
"name": "Abu Dhabi",
"countryID": "18"
}
]
}
I want to select objects from the cities array having countryID = 90 but I am stuck as the array of objects is stored in a single column city which is preventing me from doing a (*) with WHERE JSON_CONTAINS(city->'$.cities', JSON_OBEJECT('countryID', '90')).
My query looks like this and I am not getting anywhere,
SELECT JSON_EXTRACT(city, '$.cities') FROM MyTable WHERE JSON_CONTAINS(city->'$.cities', JSON_OBJECT('countryID', '90'))
It'd be a great help if someone can point me in right direction or gimme a solution to this.
Thanks
If you are using MySQL 8.0, there is a feature called JSON table functions. It converts JSON data into tabular form.Then onward you can filter the result.
The query to acheive the same is given below
Select country
FROM json_cal,
JSON_TABLE(
city,
"$.cities[*]" COLUMNS(
country JSON PATH "$",
NESTED PATH '$.countryID' COLUMNS (countryID TEXT PATH '$')
)
) AS jt1
where countryID = 90;
The DB Fiddle can be found here
More information on JSON Table functions can be found here

TypeError: list indices must be integers or slices, not str - JSON, Python error

{
"gameId": 32,
"participantIdentities": [
{
"player": {
"id": "123",
"name": "xxx",
},
"participantId": 1
},
{
"player": {
"id": "123",
"name": "yyyy",
},
"participantId": 2
}
]
"gameDuration": 143,
}
I am trying to print names in this json file in python 3
list_id = []
for info in matchinfo['participantIdentities']['player']['name']:
list_id.append(info)
But I get the following error below
TypeError: list indices must be integers or slices, not str
How do I get the content of 'name'?
There are several issues:
You provided an invalid JSON. matchinfo['participantIdentities'] should be a list but the JSON you provided is missing a closing ]
matchinfo['participantIdentities'] is a list, so you should either provide an index (matchinfo['participantIdentities'][0]['player']['summonerId'] for example) or iterate over all matchinfo['participantIdentities'] entries.
You are trying to access a key that doesn't even exist (at least in the JSON you provided). There is no 'summonerId' key anywhere.