Extract key value pair from json column in redshift - sql

I have a table mytable that stores columns in the form of JSON strings, which contain multiple key-value pairs. Now, I want to extract only a particular value corresponding to one key.
The column that stores these strings is of varchar datatype, and is created as:
insert into mytable(empid, json_column) values (1,'{"FIRST_NAME":"TOM","LAST_NAME" :"JENKINS", "DATE_OF_JOINING" :"2021-06-10", "SALARY" :"1000" }').
As you can see, json_column is created by inserting only a string. Now, I want to do something like:
select json_column.FIRST_NAME from mytable
I just want to extract the value corresponding to key FIRST_NAME.
Though my actual table is far more complex than this example, and I cannot convert these JSON keys into different columns themselves. But, this example clearly illustrates my issue.
This needs to be done over Redshift, please help me out with any valuable suggestions.

using function json_extract_path_text of Redshift can solve this problem easily, as follows:
select json_extract_path_text(json_column, 'FIRST_NAME') from mytable;

Related

check if a jsonb field contains an array

I have a jsonb field in a PostgreSQL table which was supposed to contain a dictionary like data aka {} but few of its entries got an array due to source data issues.
I want to weed out those entries. One of the ways is to perform following query -
select json_field from data_table where cast(json_field as text) like '[%]'
But this requires converting each jsonb field into text. With data_table having order of 200 million entries, this looks like bit of an overkill.
I investigated pg_typeof but it returns jsonb which doesn't help differentiate between a dictionary and an array.
Is there a more efficient way to achieve the above?
How about using the json_typeof function?
select json_field from data_table where json_typeof(json_field) = 'array'

Store SQL query result (1 column) as Array

After running my query I get 1 column result as
5
6
98
101
Is there a way to store this result as array so that I can use it later
in queries like
WHERE NOT IN ('5','6','98','101')
I am aware of storing single variable results but is this possible?
I can not use #Table variable as I will be rerunning the query again in the future and it goes out of scope
There are multiple way of storing those column data like using Temporary Tables or View or Table valued function but IMO there is no need of storing that column data anywhere. You can directly use that column in any query saying below (or) perform a JOIN which would be much better option than NOT IN
select * from
table2
where some_column not in (select column1 from this_table);
While this method is not recommended, storing an array in a single column can be done using CSV's(Comma Separated Values). Simply create a VARCHAR array and store it by storing a string containing the values in a specific order. Basically store all of your values into a string with each value being separated by a comma in that string. Store that into a column of your choice. You can later fetch the string and parse it with a string parser i.e using the .split() function in python. AGAIN I do not recommend doing this, I would instead use multiple columns, one referring to each value and access them that way instead
Using separate columns would make it easy to use in a Stored Procedure.

Compare XML data to String

I have a table that houses a bunch of data in an XML field. I can get to the data and display what I need in the select statement, but I also need to use that to compare to another table that houses a translation I am trying to do. Is there a way to compare the value being returned from the XML data to a string value that exists in another table?
The code in my select to return the XML data is:
prv.reported_attributes.value('(/row[#ATTRIBUTE="FIELD"][1])/#VALUE', 'varchar(5)')
I need to compare that text output to another table, but I keep getting NULL like the values I am trying to compare do not match. I have confirmed they do in fact have matches.

Postgres JSON selecting a row by list

I have a table that has a JSON list as one of its values. The column name is list_order and the value would be something like: [1,2,3].
I am having trouble doing a WHERE comparison to select by list_order. In pure SQL, it would be: SELECT * FROM table_name list_order=[1,2,3];
The closest example I found was this: How do I query using fields inside the new PostgreSQL JSON datatype?. However, this grabs the value of a key in the JSON where the JSON is a dictionary and not a list. I've tried modifying it to suit my need but it did not work.
Any suggestions? Is that even possible? Why is not documented? Thanks!
I found the answer. I need to compare it as text:
"SELECT * FROM table WHERE list_order::text='[1,2,3]';

sqlite data from one db to another

I have 2 sqlite databases, and I'm trying to insert data from one database to another. For example, "db-1.sqlite" has a table '1table' with 2 columns ('name', 'state'). Also, "db-2.sqlite" has a table '2table' with 2 columns ('name', 'url'). Both tables contain a list of 'name' values that are mostly common with each other but randomized, so the id of each row does not match.
I want to insert the values for the 'url' column into the db-1's table, but I want to make sure each url value goes to its corresponding 'name' value.
So far, I have done this:
> sqlite3 db-1.sqlite
sqlite> alter table 1table add column url;
sqlite> attach database 'db-2.sqlite' as db2;
Now, the part I'm not sure about:
sqlite> insert into 1table(url) select db2.2table.url from db2.2table where 1table.name==db2.2table.name
If you look at what I wrote above, you can tell what I'm trying to accomplish, but it is incorrect. If I can get any help on the matter, I'd be very grateful!!
The equality comparison operator in SQL is =, not ==.
Also, I suspect that you should be updating 1table, rather then inserting in it.
Finally, your table names start with digits, so you need to escape them.
This SQL should work better:
update `1table`
set url = (select db2.`2table`.url
from db2.`2table`
where `1table`.name = db2.`2table`.name);