1

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" ?

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

Comments

0

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';

1 Comment

Because i have to store it in jsonb, due to other requirements

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.