how to convert an object into integer array in postgress? - json

resp_data = array_to_json(array(
select jsonb_build_object(
'id', sp_authorities.db_id ,
'role_id', sp_authorities.role_id ,
'srvc_type_id', sp_authorities.srvc_type_id,
'form_data', sp_authorities.form_data ,
'sp_cust_fields_json',jsonb_agg(sp_orgs_settings.settings_data->'sp_cust_fields_json')
)
from public.cl_cf_srvc_prvdr_authorities as sp_authorities
left join public.cl_tx_orgs_settings as sp_orgs_settings
on sp_authorities.srvc_type_id = any(unnest(array(
SELECT json_array_elements_text(json_extract_path(sp_orgs_settings.settings_data,'srvc_type_id'::integer[])))
))
srvc_type_id array is not formed instead malformed array literal error is occuring
[enter image enter image description herehere](https://i.stack.imgur.com/2t1We.png)

To convert all the rows of a SELECT query into a single array, use the array_agg function.
SELECT array_agg(sp_authorities.srvc_type_id) ... -- Gives an array of raw integers
SELECT array_agg(json_build_object('id',sp_authorities.srvc_type_id)) ... -- Gives an array of json objects
SELECT array_to_json(array_agg ... -- Gives a json array of either of the above

Related

Query SQL database with JSON Value

Here is my JSON:
[{"Key":"schedulerItemType","Value":"schedule"},{"Key":"scheduleId","Value":"82"},{"Key":"scheduleEventId","Value":"-1"},{"Key":"scheduleTypeId","Value":"2"},{"Key":"scheduleName","Value":"Fixed Schedule"},{"Key":"moduleId","Value":"5"}]
I want to query the database by FileMetadata column
I've tried this:
SELECT * FROM FileSystemItems WHERE JSON_VALUE(FileMetadata, '$.Key') = 'scheduleId' and JSON_VALUE(FileMetadata, '$.Value') = '82'
but it doesn't work!
I had it working with just a dictionary key/value pair, but I needed to return the data differently, so I am adding it with key and value into the json now.
What am I doing wrong?
With the sample data given you'd have to supply an array index to query the 1th element (0-based array indexes), e.g.:
select *
from dbo.FileSystemItems
where json_value(FileMetadata, '$[1].Key') = 'scheduleId'
and json_value(FileMetadata, '$[1].Value') = '82'
If the scheduleId key can appear at arbitrary positions in the array then you can restructure the query to use OPENJSON instead, e.g.:
select *
from dbo.FileSystemItems
cross apply openjson(FileMetadata) with (
[Key] nvarchar(50) N'$.Key',
Value nvarchar(50) N'$.Value'
) j
where j.[Key] = N'scheduleId'
and j.Value = N'82'

How to return JSON property (SQL Server)

I am trying to select some data that is stored as JSON in SQL Server.
When I run isjson on the string, it returns 1.
However, I am unable to parse it.
declare #testStr nvarchar(max) = '{"order":{"address":{"shipToAddLine1":"1234 ABC Dr","shipToCityStZip":"Washington, DC 00000"}}}'
select isjson(#testStr) -- returns 1
select json_value(#testStr, '$'). -- returns null
select json_value(#testStr, '$.order') -- returns null
select #testStr -- returns entire string
How do I select the order node from the test string #testStr?
You can't use JSON_VALUE because that is not a scalar value, you need to use JSON_QUERY instead. An example of a scalar value would be the shipToAddLine1 field: select json_value(#testStr, '$.order.address.shipToAddLine1').
Using JSON_QUERY to get the order would be:
select json_query(#testStr, '$.order')
Result:
{"address":{"shipToAddLine1":"1234 ABC Dr","shipToCityStZip":"Washington, DC 00000"}}
You can use JSON_VALUE(), JSON_QUERY() and OPENJSON() to parse the input JSON. It's important to mention the following:
Function JSON_QUERY extracts an object or an array from a JSON string. If the value is not an object or an array, the result is NULL in lax mode and an error in strict mode.
Function JSON_VALUE extracts a scalar value from a JSON string. If the path points to not a scalar value, the result is NULL in lax mode and an error in strict mode
When you want to parse JSON string and get results as table, use OPENJSON table-valued function.
If you need to extract the order key you have two options - JSON_QUERY() or OPENJSON(). The following statement demonstrates how to extract a JSON object (from $.order key) and JSON values (from $.order.address.shipToAddLine1 and $.order.address.shipToCityStZip keys):
DECLARE #testStr nvarchar(max) =
N'{
"order":{
"address":{
"shipToAddLine1":"1234 ABC Dr",
"shipToCityStZip":"Washington, DC 00000"
}
}
}'
-- or
SELECT
shipToAddLine1 = JSON_VALUE(#testStr, '$.order.address.shipToAddLine1'),
shipToCityStZip = JSON_VALUE(#testStr, '$.order.address.shipToCityStZip'),
[order] = JSON_QUERY(#testStr, '$.order')
SELECT shipToAddLine1, shipToCityStZip, [order]
FROM OPENJSON(#testStr) WITH (
shipToAddLine1 nvarchar(100) '$.order.address.shipToAddLine1',
shipToCityStZip nvarchar(100) '$.order.address.shipToCityStZip' ,
[order] nvarchar(max) '$.order' AS JSON
)
Result:
shipToAddLine1 shipToCityStZip order
1234 ABC Dr Washington, DC 00000 {
"address":{
"shipToAddLine1":"1234 ABC Dr",
"shipToCityStZip":"Washington, DC 00000"
}
}

How to explode a string by comma with json object

I have a problem, I have a varchar field that contains m values ​​separated by commas:
garage 1,2
garage 1,3,5
I have the following query
select
json_object(
'data',
json_objectagg(
r.slug,
json_object(
'nome',r.name,
'localizacao',
json_object(
'endereco' , r.address,
'bairro' , r.neighborhood,
'cidade' , r.city,
'estado' , r.state,
'latitude' , r.lat,
'longitude' , r.lng
),
'tipo' , r.type,
'incorporadora' , d.name,
'dormitorios', json_object('legenda', r.rooms, 'quantidade', json_array(r.rooms_quantity)),
'garagem', json_object('legenda', r.garage, 'quantidade', json_array(r.garage_quantity)),
'metragem', json_object('legenda', r.footage, 'minimo', r.min_footage, 'maximo', r.max_footage),
'preco', json_object('minimo', IFNULL(r.min_value, 0), 'maximo' , IFNULL(r.max_value, 0)),
'capa' , ri.filename_default
)
)
) as jsonExport
from realties r
inner join developers d on r.developer_id = d.developer_id
inner join realties_images ri on r.realty_id = ri.realty_id and ri.type_image = 'cover'
where r.active = 'yes' and d.active = 'yes' and ri.active = 'yes';
But when returning json_array with integers it does not match quotes.
being this ["2,Studio"] ["1,2,3"]
but I needed it to be an array because that other code will fetch the information and I needed it
["2","Studio"] ["1","2","3"]
I already tried array_objectagg and everything is something, can anyone help me?
The best solution would be to normalize the database and avoid storing multiple values in one field.
Another solution would be to retrieve the resultset and use some kind of server scripting, process it and then convert it to JSON.
You could write your own MySQL functions to explode comma separated values, e.g like this. However, my advise would be to stick with #1. It will save you time in a long term.

How to retrieve a value in a json object in sqlite when the key is an empty string?

I am processing an sqlite table which contains json objects. These json objects have keys that are empty strings. How can I retrieve the value? For example:
select json_extract('{"foo": "bar", "":"empty"}', '$.foo') as data;
-result: "bar"
How can I retrieve "empty"?
Using your example:
sqlite> SELECT value FROM json_each('{"foo":"bar","":"empty"}') WHERE key = '';
value
----------
empty
As part of a larger query from a table:
SELECT (SELECT j.value FROM json_each(t.your_json_column) AS j WHERE j.key = '') AS data
FROM your_table AS t;

How to update a JSONB object with a parent in postgresql

I have a database with a table foo containing a column id and a column data with the following data:
{
"startDate":"2017-07-04",
"endDate":"2017-07-10",
"notDelegated":false,
"sold":false,
"disableRanking":false,
"type":"PERIOD"
}
I would like to update this data with a parent rangeData and extract the type property like this:
{
"rangeData": {
"startDate":"2017-07-04",
"endDate":"2017-07-10",
"notDelegated":false,
"sold":false,
"disableRanking":false
},
"type":"PERIOD"
}
I tried a lot of things with JSON operators in vain.
Thank you for your answers.
Use the function jsonb_build_object() and delete operator:
update foo
set data = jsonb_build_object('rangeData', data- 'type', 'type', data->'type');
In the above function call you are creating a json object with two elements:
key value
-------------------------
'rangeData' data- 'type' json object 'data' from which the key 'type' was removed
'type' data->'type' value of 'type' element of json object 'data'
SqlFiddle
You can use jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean]) (see the docs).
It's not very pretty, but I did this (you can run it yourself on this SQLFiddle I made):
SELECT
jsonb_set(
(final.range_data):: jsonb,
'{type}',
to_jsonb(final.type)
)
FROM
(
SELECT
jsonb_set(
jsonb '{}', '{rangeData}', fields.range_data
) AS range_data,
fields.type AS type
FROM
(
SELECT
data.jsonb - 'type' AS range_data,
data.jsonb ->> 'type' AS type
FROM
(
SELECT
'{"startDate":"2017-07-04","endDate":"2017-07-10","notDelegated":false,"sold":false,"disableRanking":false,"type":"PERIOD"}' :: jsonb
) data
) fields
) final;
This will get you your jsonb output of:
{"rangeData": {"startDate":"2017-07-04","endDate":"2017-07-10","notDelegated":false,"sold":false,"disableRanking":false},"type":"PERIOD"}
So you'll end up doing something like:
UPDATE
foo
SET
data = (
SELECT
jsonb_set(
(final.range_data):: jsonb,
'{type}',
to_jsonb(final.type)
)
FROM
(
SELECT
jsonb_set(
jsonb '{}', '{rangeData}', fields.range_data
) AS range_data,
fields.type AS type
FROM
(
SELECT
data.jsonb - 'type' AS range_data,
data.jsonb ->> 'type' AS type
FROM
(
SELECT
foo.data
) data
) fields
) final
);
I haven't run the final UPDATE query, but I did run the naïve SELECT statement and it got me the output as expected.
Also, caveat, I'm new to SQL (and especially the jsonb stuff), so I'm sure there will be a more performant and/or more correct "jsonb-like" way to do this. Depends on your use-case (if it's a one-off migration, or if you need to do this during every live read, etc.)