separate values from JSON in PostgreSQL - sql

I am working with a table that has one JSON column (JSONcolumn).
The values in it appear like this:
["91601","85202","78746"]
Is there any way to get all the objects from that JSON list separated into rows. I want the result to be like this:
JSONcolumn
91601
85202
78746
I read a lot of answers on how to do it but the difference that I noticed is that in my case, the JSON contains a LIST and in the most of cases the people answered using queries that work if the JSON contains a DICT

First it is JSON Array and Object not List and Dict. List and dict are Python terms.
Second the documentation has a whole section JSON operators and functions that cover this.
Third what you want is:
select * from json_array_elements_text('["91601","85202","78746"]');
value
-------
91601
85202
78746
--Or
select * from json_array_elements('["91601","85202","78746"]');
value
---------
"91601"
"85202"
"78746"

Related

Hive sql extract one to multiple values from key value pairs

I have a column that looks like:
[{"key_1":true,"key_2":true,"key_3":false},{"key_1":false,"key_2":false,"key_3":false},...]
There can be 1 to many items described by parameters in {} in the column.
I would like to extract values only of parameters described by key_1. Is there a function for that? I tried so far json related functions (json_tuple, get_json_object) but each time I received null.
Consider below json path.
WITH sample_data AS (
SELECT '[{"key_1":true,"key_2":true,"key_3":false},{"key_1":false,"key_2":false,"key_3":false}]' json
)
SELECT get_json_object(json, '$[*].key_1') AS key1_values FROM sample_data;
Query results

How to access nested arrays and JSON in AWS Athena

I'm trying to process some data from s3 logs in Athena that has a complex type I cannot figure out how to work with.
I have a table with rows such as:
data
____
"[{\"k1\":\"value1\", \"key2\":\"value2\"...}]"
I'd like to treat it as (1) an array to extract the first element, and then that first element as the JSON that it is.
Everything is confused because the data naturally is a string, that contains an array, that contains json and I don't even know where to start
You can use the following combination of JSON commands:
SELECT
JSON_EXTRACT_SCALAR(
JSON_EXTRACT_SCALAR('"[{\"k1\":\"value1\", \"key2\":\"value2\"...}]"','$'),
'$[0].k1'
)
The inner JSON_EXTRACT_SCALAR will return the JSON ARRAY [{"k1":"value1", "key2":"value2"...}] and the outer will return the relevant value value1
Another similar option is to use CAST(JSON :
SELECT
JSON_EXTRACT_SCALAR(
CAST(JSON '"[{\"k1\":\"value1\", \"key2\":\"value2\"...}]"' as VARCHAR),
'$[0].k1'
)

how do I write a query to select element that has a tag id in an array of tag ids with SQL?

I am trying to create an SQL query using PRESTO DATABASE to get ticket numbers that have a tag applied. The tags are in the ticket_tag column but the ticket tag column's rows each have an array of all tag ids the ticker has. I want to scan the array and verify that the tag id I am looking for is in it so I can select or return only those ticket numbers. Can someone help?
all_tickets_tags looks like this:
[999170833505476,12403428395,12706673982,104100556289383,202231716456598,430869490433479,605189679499805,928941873813160]
they are tag id's.
SELECT ticker_number, ticket_tags
FROM ticket_activity
WHERE all_ticket_tags = 513515886108503
You can use contains function.
contains(all_ticket_tags, 513515886108503)
If the array is just a string you can match with a SQL LIKE statement.
...
WHERE all_ticket_tags LIKE '%tag%'
Alternatively and more correctly, you can unnest the array or use a function like contains that is custom built for array structure, but it will depend on the actual format of the field in question.

Search JSON column for JSON that contains a specific value

I have a postgresql database with a table called choices, in the choices table I have a column called json that contains JSON entries, for example: [1,2,3]
I need a query that returns all entires that contains a specific value.
For example I have the following entries:
[1,2,3] [6,7,1] [4,5,2]
I want to get all entries that contain the value 1 so it would return:
[1,2,3]
[6,7,1]
Thanks,
demo: db<>fiddle
The json_array_elements_textfunctions expands the json arrays into one row each element (as text). With that you can filter it by any value you like.
SELECT
json_data
FROM choices, json_array_elements_text(json_data) elem
WHERE value = '1'
Documentation: JSON functions
Please notice that "json" is a the name for the json type in PostgreSQL. You should better rename your column to avoid some conflicts. (I called mine json_data)

Get an average value for element in column of arrays of json data in postgres

I have some data in a postgres table that is a string representation of an array of json data, like this:
[
{"UsageInfo"=>"P-1008366", "Role"=>"Abstract", "RetailPrice"=>2, "EffectivePrice"=>0},
{"Role"=>"Text", "ProjectCode"=>"", "PublicationCode"=>"", "RetailPrice"=>2},
{"Role"=>"Abstract", "RetailPrice"=>2, "EffectivePrice"=>0, "ParentItemId"=>"396487"}
]
This is is data in one cell from a single column of similar data in my database.
The datatype of this stored in the db is varchar(max).
My goal is to find the average RetailPrice of EVERY json item with "Role"=>"Abstract", including all of the json elements in the array, and all of the rows in the database.
Something like:
SELECT avg(json_extract_path_text(json_item, 'RetailPrice'))
FROM (
SELECT cast(json_items to varchar[]) as json_item
FROM my_table
WHERE json_extract_path_text(json_item, 'Role') like 'Abstract'
)
Now, obviously this particular query wouldn't work for a few reasons. Postgres doesn't let you directly convert a varchar to a varchar[]. Even after I had an array, this query would do nothing to iterate through the array. There are probably other issues with it too, but I hope it helps to clarify what it is I want to get.
Any advice on how to get the average retail price from all of these arrays of json data in the database?
It does not seem like Redshift would support the json data type per se. At least, I found nothing in the online manual.
But I found a few JSON function in the manual, which should be instrumental:
JSON_ARRAY_LENGTH
JSON_EXTRACT_ARRAY_ELEMENT_TEXT
JSON_EXTRACT_PATH_TEXT
Since generate_series() is not supported, we have to substitute for that ...
SELECT tbl_id
, round(avg((json_extract_path_text(elem, 'RetailPrice'))::numeric), 2) AS avg_retail_price
FROM (
SELECT *, json_extract_array_element_text(json_items, pos) AS elem
FROM (VALUES (0),(1),(2),(3),(4),(5)) a(pos)
CROSS JOIN tbl
) sub
WHERE json_extract_path_text(elem, 'Role') = 'Abstract'
GROUP BY 1;
I substituted with a poor man's solution: A dummy table counting from 0 to n (the VALUES expression). Make sure you count up to the maximum number of possible elements in your array. If you need this on a regular basis create an actual numbers table.
Modern Postgres has much better options, like json_array_elements() to unnest a json array. Compare to your sibling question for Postgres:
Can get an average of values in a json array using postgres?
I tested in Postgres with the related operator ->>, where it works:
SQL Fiddle.