I have the return of a json in the children column of the table. How can I loop over the title values present in the children column?
Example of JSON present in a table row.
[
{
"id": "5CBDE9F2-5D81-4CA9-8302-0908104558D9",
"title": "Title 1",
"Code": "5874"},
{
"id": "9BFC4A6C-9BDC-4C15-B01F-5B87683AE50F",
"title": "Title 2",
"Code": "6582"
}
]
I know using the [key] doesn't work. But like [0] or [2] I get it. How can I interact?
SELECT *
FROM vwJSONFilhos A
WHERE json_value(Filhos,'$[key].title') = 'Title 2'
Related
I can't get a specific row from this JSON array.
So I want to get the object where filed 'type' is equal to 'No-Data'
Are there exist any functions in SQL to take the row or some expressions?
"metadata": { "value": "JABC" },
"force": false
"users": [
{ "id": "111", "comment": "aaa", type: "Data" },
{ "id": "222", "comment": "bbb" , type:"No-Data"},
{ "id": "333", "comment": "ccc", type:"Data" }
]
You can use a JSON path query:
select jsonb_path_query_first(the_column, '$.users[*] ? (#.type == "No-Data")')
from the_table
This assumes that the column is defined as jsonb (which it should be). If it's not you have to cast it: the_column::jsonb
Online example
I have a JSON column (_col0) like below and wanted to update only the 'name' part of json to new value.
{
"id":"1234",
"name":"Demo 1",
"attributes":[
{
"id": "1122",
"name": "affiliate",
"type": "number"
}
],
"behaviors": [
{
"id": "246685",
"name": "Email Send",
"scheduleOption": null,
"defaultTimeFilterEnabled": true,
"schema": []
}
]
}
I wanted to only change value of the outer "name" parameter from 'Demo 1' to 'Demo 2'. The SQL I tried does change the name parameter but makes the rest all to null.
select transform_values(cast(json_parse(_col0) as MAP(varchar, json)) , (k, v) -> if(k='name','Demo 2')) from table1
if has overload with 3 parameters, the 3rd being value for false case, use it to return the current value (you will need to transform either you varchar literal to json or json value to varchar):
-- sample data
WITH dataset (json_str) AS (
VALUES ('{
"id":"1234",
"name":"Demo 1",
"attributes":[
{
"id": "1122",
"name": "affiliate",
"type": "number"
}
],
"behaviors": [
{
"id": "246685",
"name": "Email Send",
"scheduleOption": null,
"defaultTimeFilterEnabled": true,
"schema": []
}
]
}')
)
-- query
select transform_values(
cast(json_parse(json_str) as MAP(varchar, json)),
(k, v)->if(k = 'name', cast('Demo 2' as json), v)
)
from dataset
Output:
_col0
{behaviors=[{"id":"246685","name":"Email Send","scheduleOption":null,"defaultTimeFilterEnabled":true,"schema":[]}], name="Demo 2", attributes=[{"id":"1122","name":"affiliate","type":"number"}], id="1234"}
I am constructing an interface between a PostgreSQL system and a SQL Server system and am attempting to "flatten" the structure of the JSON data to facilitate this. I'm very experienced in SQL Server but I'm new to both PostgreSQL and JSON.
The JSON contains essentially two types of structure: those of type "text" or "textarea" where the value I want is in an object named value (the first two cases below) and those of type "select" where the value object points to an id object in a lower-level options array (the third case below).
{
"baseGroupId": {
"fields": [
{
"id": "1f53",
"name": "Location",
"type": "text",
"options": [],
"value": "Over the rainbow"
},
{
"id": "b547",
"name": "Description",
"type": "textarea",
"options": [],
"value": "A place of wonderful discovery"
},
{
"id": "c12f",
"name": "Assessment",
"type": "select",
"options": [
{
"id": "e5fd",
"name": "0"
},
{
"id": "e970",
"name": "1"
},
{
"id": "0ff4",
"name": "2"
},
{
"id": "2db3",
"name": "3"
},
{
"id": "241f",
"name": "4"
},
{
"id": "3f52",
"name": "5"
}
],
"value": "241f"
}
]
}
}
Those with a sharp eye will see that the value of the last value object "241f" can also be seen within the options array against one of the id objects. When nested like this I need to extract the value of the corresponding name, in this case "4".
The JSON-formatted information is in table customfield field textvalue. It's datatype is text but I'm coercing it to json. I was originally getting array set errors when trying to apply the criteria in a WHERE clause and then I read about using a LATERAL subquery instead. It now runs but returns all the options, not just the one matching the value.
I'm afraid I couldn't get an SQL Fiddle working to reproduce my results, but I would really appreciate an examination of my query to see if the problem can be spotted.
with cte_custombundledfields as
(
select
textvalue
, cfname
, json_array_elements(textvalue::json -> 'baseGroupId'->'fields') ->> 'name' as name
, json_array_elements(textvalue::json -> 'baseGroupId'->'fields') ->> 'value' as value
, json_array_elements(textvalue::json -> 'baseGroupId'->'fields') ->> 'type' as type
from
customfield
)
, cte_custombundledfieldsoptions as
(
select *
, json_array_elements(json_array_elements(textvalue::json -> 'baseGroupId'->'fields') -> 'options') ->> 'name' as value2
from
cte_custombundledfields x
, LATERAL json_array_elements(x.textvalue::json -> 'baseGroupId'->'fields') y
, LATERAL json_array_elements(y -> 'options') z
where
type = 'select'
and z ->> 'id' = x.value
)
select *
from
cte_custombundledfieldsoptions
I posted a much-simplified rewrite of this question which was answered by Bergi.
How do I query a string from JSON based on another string within the JSON in PostgreSQL?
I have a JSON column with following JSON
{
"metadata": { "value": "JABC" },
"force": false,
"users": [
{ "id": "111", "comment": "abc" },
{ "id": "222", "comment": "abc" },
{ "id": "333" }
]
}
I am expecting list of IDs from the query output ["111","222", "333"]. I tried following query but getting null value.
select colName->'users'->>'id' ids from tableName
How to get this specific field value from the array of object?
You need to extract the array as rows and then get the id:
select json_array_elements(colName->'users')->>'id' ids from tableName;
If you're using jsonb rather than json, the function is jsonb_array_elements.
I have a jason column in my postgress sql Database. I have several properties in that jason column. I can search properties using below query.
SELECT * FROM public.object_reference where value->>'name' = 'Sam' and value->>'address' ='home';
But my problem is I have a Array inside that JSON column. That Array has key and value pair. Below is the sample of that array
"attributes": [ {
"value": "Sam",
"key": "name"
}, {
"value": "abc",
"key": "address"
}, {
"value": "Singapore",
"key": "country"
}, {
"value": "97813245",
"key": "mobile"
}, {
"value": "Engineer",
"key": "position"
},
"id": "1312312",
"type": "Job",
"classid": "1245568956643546788907634"
}
So i need to get the value of name in the attributes array (inside JSON column). This is json type column, not a jsonb type.
You can deconstruct the array inside de object transforming it in a set of recordet (pseudo table) with json_array_elements:
select pair->>'value'
from has_json,json_array_elements(obj->'attributes') as pair
where pair->>'key' = 'name';
You can see a running example at: http://rextester.com/ONJZ8486