I have the following JSON which is stored in a jsonb field named "Data" in a PostgreSQL database:
{
"CompetitionData" :
{
"StartDate" : "12.06.2018",
"Name" : "TestCompetition",
"Competitors" :
[
{
"Id" : "100",
"Name" : "John",
"Age" : "24",
"Score" : "98",
"Shoes":
{
"Brand" : "Nike"
}
},
{
"Id" : "200",
"Name" : "Adam",
"Age" : "32",
"Score" : "78",
"Shoes":
{
"Brand" : "Adidas"
}
}
]
}
}
Im trying to get a specific entry in Competitors, like e.g.
SELECT * FROM Competitors WHERE Shoes = "Nike";
And the result must look like this:
{
"Id" : "100",
"Name" : "John",
"Age" : "24",
"Score" : "98",
"Shoes":
{
"Brand" : "Nike"
}
}
I tried the following query, but i keeps returning all competitors:
SELECT jsonb_array_elements(public."Competitions"."Data"->'CompetitionData'->'Competitors') as test
FROM public."Competitions" WHERE public."Competitions"."Data" #> '{"CompetitionData":{"Competitors":[{"Shoes":{"Brand":"Nike"}}]}}';
Is it possible to return just the competitor with Shoe Brand "Nike" ?
Use jsonb_array_elements in the from clause
SELECT j.* FROM
t cross join lateral
jsonb_array_elements(data->'CompetitionData'->'Competitors') as j(comp)
where j.comp->'Shoes'->>'Brand' = 'Nike'
Demo
Why do you want to save it in jsonb? Just normalize it into a database:
CREATE TABLE competitor_shoe (
name text PRIMARY KEY,
brand text NOT NULL
);
CREATE TABLE competitor (
id int PRIMARY KEY,
name text NOT NULL,
age int NOT NULL,
score int NOT NULL,
shoe text NOT NULL REFERENCES competitor_shoe(name)
);
CREATE TABLE competition (
name text PRIMARY KEY,
start_date date NOT NULL
);
CREATE TABLE competition_competitor (
competition text REFERENCES competition,
competitor int REFERENCES competitor,
PRIMARY KEY (competition,competitor)
);
INSERT INTO competitor_shoe
VALUES ('shoes1', 'Nike'),
('shoes2', 'Adidas');
INSERT INTO competitor
VALUES (100,'John',24,98,'shoes1'),
(200,'Adam',32,78,'shoes2');
INSERT INTO competition
VALUES (
'TestCompetition',
'12.06.2018'
);
INSERT INTO competition_competitor
VALUES ('TestCompetition', 100), ('TestCompetition', 200);
-- query the data
SELECT *
FROM competitor c
JOIN competitor_shoe cs
ON c.shoe = cs.name
WHERE brand = 'Nike';
-- query the data and return it as json object
SELECT to_jsonb(c) || jsonb_build_object('shoe', to_jsonb(cs)) as data
FROM competitor c
JOIN competitor_shoe cs
ON c.shoe = cs.name
WHERE brand = 'Nike';
Related
DECLARE #json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
]
}
}'
SELECT * FROM OPENJSON(#json, '$.pets.cats') WITH --we have the "main" json address here
(
id INT '$.id', --sub-address
name varchar(10) '$.name', --sub-address
sex varchar(10) '$.sex' --sub-address
)
The results are:
id
name
sex
1
Fluffy
Female
2
Long Tail
Female
3
Scratch
Male
I want to include another column which will not depend on the JSON, but be a custom specified string ("mammal"), so that the output is like this:
id
name
sex
Type
1
Fluffy
Female
mammal
2
Long Tail
Female
mammal
3
Scratch
Male
mammal
How would I achieve this?
You can simply add a constant in your SELECT statement:
DECLARE #json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
]
}
}'
SELECT *, 'mammal' AS Type FROM OPENJSON(#json, '$.pets.cats') WITH --we have the "main" json address here
(
id INT '$.id', --sub-address
name varchar(10) '$.name', --sub-address
sex varchar(10) '$.sex' --sub-address
)
I use PostgreSQL 10.11 and would want to enter the following structure into a jsonb field:
{
lead: {
name: string,
prep: boolean
},
secondary: {
{
name: string,
prep: boolean
},
{
name: string,
prep: boolean
}
}
so lead is an object with name and prep and secondary is an array of name and preps.
How can I do that? The scripts below is to create a table with jsonb field:
CREATE TABLE public.test01 (
name JSONB DEFAULT '{}'::jsonb NOT NULL
)
WITH (oids = false);
ALTER TABLE public.test01
ALTER COLUMN id SET STATISTICS 0;
COMMENT ON COLUMN public.test01.name
IS '''[]''';
ALTER TABLE public.test01
OWNER TO postgres;
I'm trying this insert but get error:
INSERT INTO
public.test01
(
name
)
VALUES
('
{"lead":
"name": "Paint house",
"prep": "yes"}
,
"Secondary":
"name": "John",
"prep", "No"}
}
');
It's the first time I'm using jsonb so a select example would also be helpful to know hoe to read the data as well.
Your JSON is malformed. Presumably, you meant:
INSERT INTO public.test01 (name)
VALUES (
'{
"lead": {
"name": "Paint house",
"prep": "yes"
},
"Secondary": {
"name": "John",
"prep": "No"
}
}'::jsonb);
Demo on DB Fiddle
I have a table with following definition:
CREATE TABLE USER_CONFIGURATIONS (
ID BIGSERIAL PRIMARY KEY,
DATA JSONB
);
I have a data field that looks like this :
[
{
"user_id": 1,
"user_name": "demo_user",
"is_manager": 1,
"options": [
{
"phone":{
"home":"XXXXXXX",
"work":"XXXXXXX"
},
"address":{
"home":"XXXXXXX",
"work":"XXXXXXX"
}
}
]
},
...
]
questions:
how to update "user_name" ?
how to update "options->phone->home" ?
UPDATE USER_CONFIGURATIONS SET DATA = jsonb_set(...) WHERE ...user_id=1;
postgres 9.6 version.
i tried with jsonb_set() but not wokring
https://www.db-fiddle.com/f/4ZYZiuJr4QgfNkzyTCeT1X/1
just run it twice:
update USER_CONFIGURATIONS
set data =
jsonb_set(
jsonb_set(
data,'{0,"user_name"}','"blah"'
), '{0,"options",0,"phone","home"}','999999'
)
where id =1
;
Table :
CREATE TABLE profit_center
(
id serial NOT NULL,
name character varying,
site_id integer,
CONSTRAINT profit_center_pkey PRIMARY KEY (id),
CONSTRAINT profit_center_name_site_id_key UNIQUE (name, site_id)
);
http://sqlfiddle.com/#!17/04630/4
Query which I have tried :
select site_id,json_build_object(name,id) as jsn from profit_center;
I want to group by all the jsn values by site_id. Expected result in single row :
{
"1": {
"Darshan": "1",
"ABC": 2
},
"2": {
"XYZ": 3
}
}
looks bad, but returns your expected result:
with r as (select concat('"',site_id,'": ',concat('{',string_agg(concat('"',name,'": ',id),','),'}')::json) from profit_center group by site_id)
select concat('{',string_agg(concat,','),'}')::json from r;
We are using Postgres DB , in that we have one table contains column of type JSON , format is like below
{
"name" : "XXX",
"id" : "123",
"course" :[
{
"name" : "java",
"tutor":"YYYY"
},
{
"name" : "python",
"tutor":"ZZZZ"
}
]
}
{
"name" : "XXX",
"id" : "123",
"course" :[
{
"name" : "java",
"tutor":"YYYY"
},
{
"name" : "python",
"tutor":"ZZZZ"
}
]
}
like this for example we have two rows , and in the json column we have each like above
i want to Postgre query , which will check the number of elements in the course array and if it is more than one , then only return that row
am not getting how to count the array elements from inside the json key
can any please suggest
why not just json_array_length?.. eg:
f=# with c(j) as (values('{
"name" : "XXX",
"id" : "123",
"course" :[
{
"name" : "java",
"tutor":"YYYY"
},
{
"name" : "python",
"tutor":"ZZZZ"
}
]
}'::json))
select json_array_length(j->'course') from c;
json_array_length
-------------------
2
(1 row)
so smth like
select * from table_name where json_array_length(j->'course') > 1