Postgresql JSON column check value exists in array of json - sql

I have a database schema like the following where I have a Children record table
CREATE TABLE Children (
name varchar(100),
friends JSON NOT NULL,
);
INSERT INTO Children (name,friends)
VALUES('Sam',
array['{"name":"Rakesh","country":"Africa"}',
'{"name":"Ramesh","country":"India"}']::json[]);
Now I need to query the data and display it only if the name of the friend is like '%Ra'. Structure of the JSON data is consistent.

If you have json[] as data type then you can use unnest and then write your query, or if it is json then you can use json_array_elements.
Below code considers json[] data type -
select * from Children
where name in (
select name from (
select name, unnest(friends) as friend from Children
) i
where i.friend->>'name' like '%Ra');
DBFiddle

Related

Scala, Doobie, PostgreSQL - how to select from array/jsonb column?

I have a simple db table:
create table if not exists players
(
id bigint,
name text,
results text[]
);
Now I would like to create select query, where I want only rows with passed results. So I created a scala code with doobie:
def getPlayers(id: Int, result: String): Query[Int] = {
sql"select id from players where results ? $result".query[Int]
}
But it didn't work as expected. My question is how to select from array column in postgresql? Currently I have results as an array, but I could change it to jsonb if it is easier.
You can use the following query:
select id from players where $result = any(results);
You can find more information here:
https://www.postgresql.org/docs/current/functions-comparisons.html

How to flatten a json structure in HIVE?

I have a JSON structure that looks like this.
There is a structure nested in a column.
HEADER:
{"user":{"location":"USA","id":1514008171,"name":"Auzzie Jet","screenname":"metalheadgrunge","geoenabled":false},"tweetmessage":"Anthrax - Black - Sunglasses hell","createddate":"2013-06-20T12:08:44","identifier":"1234","geolocation":null}
When I query this, this works:
SELECT *
FROM TBL a
WHERE header.identifier = '1234'
But then, when I want to find the location from the nested json structure. It does not work:
SELECT *
FROM TBL a
WHERE header.identifier = '1234'
and a.header.user.location LIKE '%USA%'
Does anyone know how to query this in HIVE?
For flattening json structure you need to first create lateral view using json_tuple that's how you can be able to achieve what you intend to.
Please find the complete solution how to do it.
Step 1: Create external table tweets with single column tweet with data type of string.
CREATE EXTERNAL table tweets (tweet string);
Now put the json string
{"user":{"location":"USA","id":1514008171,"name":"Auzzie Jet","screenname":"metalheadgrunge","geoenabled":false},"tweetmessage":"Anthrax - Black - Sunglasses hell","createddate":"2013-06-20T12:08:44","identifier":"1234","geolocation":null}
Step 2: In text file named tweets.txt and run the below command to load the data from text file into hive table.
LOAD data local inpath 'tweets.txt' into table tweets;
Once done, now we are ready to play on our Json string.
So basically here what we are trying to achieve is querying on identifier and location fields which are basically at different levels.
user
location : USA
id : 1514008171
name : Auzzie Jet
screenname : metalheadgrunge
geoenabled : false
tweetmessage : Anthrax - Black - Sunglasses hell
createddate : 2013-06-20T12:08:44
identifier : 1234
geolocation : null
Level 1 fields are => user, tweetmessage, createddate,identifier, geolocation
Level 2 Fields are => location, id, name, screenname, geoenabled
So firstly we need to create lateral View on Level 1 so that we can query on Level 1 fields. In our example we need to query on identifier. Also to query on Level 2 fields we need to explode our User view which would be possible by lateral view.
LATERAL VIEW json_tuple(t.tweet, 'user', 'identifier' ) t1 as `user`, `identifier`
and then to query on location, we need to create another lateral view for level 2 fields.
LATERAL VIEW json_tuple(t1.`user`,'name', 'location') t2 as `name`, `location`
and that's it finally we can use select on tweets with lateral views.
Step 3 and Final Query:
SELECT t.* FROM tweets t LATERAL VIEW json_tuple(t.tweet, 'user', 'identifier' ) t1 as `user`, `identifier` LATERAL VIEW json_tuple(t1.`user`,'name', 'location') t2 as `name`, `location` where t1.`identifier`=1234 and `location` ="USA";
For more read on lateral view :LateralView
and on Json_Tuple : JsonTuple

copy data from 2 separate tables in postgresql

Just wondering is it possible to extract data from 2 different tables at one time in postgresql
I have the following:
Blocks Table - has been created as follows in order to fit a schema, so the JSON information has all been stored in an information column containing 36 polygons each
UUID (UUID)
Name (TEXT)
Type (TEXT)
Information (TEXT)
815b2ce7-ce99-4d6c-b41a-bec512173f53
C2
Block
'stored JSON info'
7a9a03fc-8be6-47ca-b743-43715ebb5610
D2
Block
'stored JSON info'
9136dcda-2a55-4084-87c1-68ccde23aed8
E3
Block
'stored JSON info'
For a later query, I need to know the geometries of each of the polygons, so I created another table using a code which parsed them out:
CREATE TABLE blockc2_ AS SELECT geom FROM (SELECT elem->>'type' AS type, elem->'properties' AS prop, elem->'geometry' AS geom FROM (SELECT json_array_elements(data) elem FROM block) f1)f2;
A final table is created to show just the geometries (which will a associated with the already created UID's like below
new_table
UUID (UUID)
Geometry (Geometry)
815b2ce7-ce99-4d6c-b41a-bec512173f53
01030000000100000005000000972E05A56D6851C084D91C434C6C32401C05D4886B6851C086D974FA4D6C324078F4DA916D6851C036BF7504766C3240F31D0CAE6F6851C035BF1D4D746C3240972E05A56D6851C084D91C434C6C3240
7a9a03fc-8be6-47ca-b743-43715ebb5610
01030000000100000005000000BB05694F726851C0CB2A87A8486C32403EDC3733706851C0CD2ADF5F4A6C32409ACB3E3C726851C07E10E069726C324017F56F58746851C07C1088B2706C3240BB05694F726851C0CB2A87A8486C3240
9136dcda-2a55-4084-87c1-68ccde23aed8
1030000000100000005000000972E05A56D6851C084D91C434C6C32401C05D4886B6851C086D974FA4D6C324078F4DA916D6851C036BF7504766C3240F31D0CAE6F6851C035BF1D4D746C3240972E05A56D6851C084D91C434C6C3240
Ideally, I need a code like below (if its possible) because if I insert them separately they don't associate with each other. Instead of 3 rows of info, it will be 6 (3 UUIDS and 3 Geometries)
INSERT INTO new_table (uuid, geometry) SELECT UUID FROM blocks WHERE Name='C2' AND SELECT geometry FROM second_table WHERE Name='C2'
Is something like this possible?
create table C (select * from table B union all select * from table A)
This sounds like a join:
INSERT INTO new_table (uuid, geometry)
SELECT b.UUID, g.geometry
FROM blocks b JOIN
geometry g
USING (name)
WHERE Name = 'C2';

Getting values from array of objects jsonb postgresql

I am storing some ids and names in a jsonb array of object like this
[{"id":"1","name":"abc"},{"id":"2","name":"cde"}]
My table looks like this
id userinfo
1 [{"id":"1","name":"abc"},{"id":"2","name":"cde"}]
2 [{"id":"3","name":"fgh"},{"id":"4","name":"ijk"}]
I am trying to select all the records with id 1 but I just want to get ids in userinfo object I don't want names
I tried this
select distinct userinfo->'name' from table where id = 1
but this is giving me null value
This will work with this query
select distinct userinfo->0->'name' from table where id = 1
but I don't know the index so how can I use this query to get my desired result
Thanks
You need to normalize the data by unnesting the array, then you can access each element.
select ui.info ->> 'id' as id,
ui.info ->> 'name' as name
from the_table t
cross join lateral jsonb_array_elements(t.userinfo) as ui(info)
where t.id = 1;
Online example: http://rextester.com/FCNM11312

Dynamic Columns in

I have table with the following static columns
ID Sys_Date Name prop_name1 prop_name2 prop_name3 prop_value1 prop_value2 prop_value3
10 11/2/2011Java class method parameter Imanager getOrders orderNumber
I need to write SQL query which get an input property name like “method” and go over (prop_name1 prop_name2 prop_name3 ) and check which column
Is equal to “method” in case I found it I need to jump 3 columns to the proper value which is “getOrders” and get the value from there where
prop_name1 is mapping to prop_value1
prop_name2 is mapping to prop_value2
prop_name3 is mapping to prop_value3
how can I do it with sql query?
Thanks in advance
You could do something like this:
select name,value
from
(
select id, prop_name name, prop_name value
from table
union
select id, prop_name2 name, prop_name2 value
from table
union
select id, prop_name3 name, prop_name3 value
from table
)
where name = 'method'
...which is basically shoe-horning your data into a more easily queryable structure. You'd be better off changing the table structure, though..