How to get each JSON child of an array, postgreSQL - sql

I have postgreSQL 9.3 and working with json, my field json in DB looks like:
{
"route_json": [
{
"someKeys": "someValues",
"time": 123
},
{
"someKeys": "someValues",
"time": 123
}, ... N
]
}
In my case I need to catch the 'time' element from each element of route_json array and set them in new array. Is there any way to do this.

It’s not pretty:
SELECT
value->'time'
FROM
json_array_elements('{"route_json": [{"someKeys": "someValues","time": 123},{"someKeys": "someValues","time": 456}]}'::json->'route_json');

Related

Fetching second maximum date json object(postgres)

I'm trying to fetch second max date json data from an json column..
Here is jsonb column
--------
value
--------
{
"id": "90909",
"records": [
{
"name":"john",
"date": "2016-06-16"
},
{
"name":"kiran",
"date": "2017-06-16"
},
{
"name":"koiy",
"date": "2018-06-16"
}
]
}
How to select the second maximum date json object in the jsonb column..
expected output:-
{
"name":"kiran",
"date": "2017-06-16"
}
and if we have only one object inside the records means that will be the second max date
and any suggestions would also helpful..
one way of doing it could be, get all the dates in an array, then sort the array in DESC and then get the second date. all these steps can be done in a single query

Query for entire JSON document in nested JSON schema

Background:
I wish to locate the entire JSON document that has a condition where "state" = "new" and where length(Features.id) > 4
{
"id": "123"
"feedback": {
"Features": [
{
"state": "new"
"id": "12345"
}
]
}
}
This is what I have tried to do:
Since this is a nested document. My query looks like this:
A stackoverflow member has helped me to access the nested contents within the query, but is there a way to obtain the full document
I have used:
SELECT VALUE t.id FROM t IN f.feedback.Features where t.state = 'new' and length(t.id)>4
This will give me the ids.
My desire is to have access to the full document with this condition?
{
"id": "123"
"feedback": {
"Features": [
{
"state": "new"
"id": "12345"
}
]
}
}
Any help is appreciated
Try this
SELECT *
FROM f
WHERE
f.feedback.Features[0].state = 'new'
AND length(f.feedback.Features[0].id)>4
Here is the SELECT spec for CosmosDB for more details
https://learn.microsoft.com/en-us/azure/cosmos-db/sql-query-select
Also, check out "working with JSON" in CosmosDB notes
https://learn.microsoft.com/en-us/azure/cosmos-db/sql-query-working-with-json
If the Features array has more than 1 value, you can use EXISTS clause to search within them. See specs of EXISTS here with examples:
https://learn.microsoft.com/en-us/azure/cosmos-db/sql-query-subquery#exists-expression

Returning unknown JSON in a query

Here is my scenario. I have data in a Cosmos DB and I want to return c.this, c.that etc as the indexer for Azure Cognitive Search. One field I want to return is JSON of an unknown structure. The one thing I do know about it is that it is flat. However it is my understanding that the return value for an indexer needs to be known. How, using SQL in a SELECT, would I return all JSON elements in the flat object? Here is an example value I would be querying:
{
"BusinessKey": "SomeKey",
"Source": "flat",
"id": "SomeId",
"attributes": {
"Source": "flat",
"Element": "element",
"SomeOtherElement": "someOtherElement"
}
}
So I would want my select to be maybe something like:
SELECT
c.BusinessKey,
c.Source,
c.id,
-- SOMETHING HERE TO LIST OUT ALL ATTRIBUTES IN THE JSON AS FIELDS IN THE RESULT
And I would want the result to be:
{
"BusinessKey": "SomeKey",
"Source": "flat",
"id": "SomeId",
"attributes": [{"Source":"flat"},{"Element":"element"},{"SomeOtherElement":"someotherelement"}]
}
Currently we are calling ToString on the c.attributes, which is the JSON of unknown structure but it is adding all the escape characters. When we want to search the index, we have to add all those escape characters and it's getting really unruly.
Is there a way to do this using SQL?
Thanks for any help!
You could use UDF in cosmos db sql.
UDF code:
function userDefinedFunction(object){
var returnArray = [];
for (var key in object) {
var map = {};
map[key] = object[key];
returnArray.push(map);
}
return returnArray;
}
Sql:
SELECT
c.BusinessKey,
c.Source,
c.id,
udf.test(c.attributes) as attributes
from c
Output:

How to check if json array already contains a certain key?

Let's say I have this json in my jsonb column
{
"fields": [
{
"name": "firstName",
},
{
"name": "lastName",
},
...
}
How can I know if the "firstName" already exist?
I've tried this so far
SELECT field->>'fields'
from person where (field->'name')::jsonb ? 'firstName';
Use the containment operator #>:
select field->>'fields'
from person
where field->'fields' #> '[{"name": "firstName"}]'
you can use json_array_elements to generate fields elements so you can filter based on 'name'.
SELECT field->>'fields', obj.*
from person, jsonb_array_elements_text(field->'fields') obj
where obj = '{"name": "firstName"}'
see dbfiddle

SQL Server query JSONobject to get aggregated values

I have a JSON object stored in SQL Server, in a nvarchar(max) column. The JSON looks like this:
{
"data": [{
"RespID": 3512,
"ObsPriceValue": 2.34
}, {
"RespID": 4904,
"ObsPriceValue": 2.54
}, {
"RespID": 5127,
"ObsPriceValue": 3.44
}]
}
The above example array is made up of three items, but I don't know how many items are present in the record, and they can be 2 as well as up to 30.
Each row in the table has an object like the above.
I'd like to get, in a single query, the average value of the field ObsPriceValue
I've tried with JSON_QUERY, but I have always to specify the index of the element.
Is there a way to get it or the JSON schema the data is stored is wrong?
Next approach may help. You need to use OPENJSON() with explicit schema definition to return a table with ObsPriceValue column:
JSON:
DECLARE #json nvarchar(max) = N'{"data": [{
"RespID": 3512,
"ObsPriceValue": 2.34
}, {
"RespID": 4904,
"ObsPriceValue": 2.54
}, {
"RespID": 5127,
"ObsPriceValue": 3.44
}]
}'
Statement:
SELECT AVG(ObsPriceValue) AS AvgObsPriceValue
FROM OPENJSON(#json, '$.data') WITH (
ObsPriceValue numeric(10, 2) '$.ObsPriceValue'
) j
Output:
----------------
AvgObsPriceValue
----------------
2.773333