在PostgreSQL中选择JSON中的特定条目

时间:2019-03-08 10:18:33

标签: sql json postgresql asp.net-core jsonb

我有以下JSON,它存储在PostgreSQL数据库中名为“ Data”的jsonb字段中:

{
    "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"
                }
            }
        ]
    }
}

我正在尝试在竞争对手中获取特定的条目,例如

SELECT * FROM Competitors WHERE Shoes = "Nike";

结果必须如下所示:

{
       "Id" : "100",
       "Name" : "John",
       "Age" : "24",
       "Score" : "98",
       "Shoes":
       {
           "Brand" : "Nike"
       }
}

我尝试了以下查询,但我不断返回所有竞争对手:

SELECT jsonb_array_elements(public."Competitions"."Data"->'CompetitionData'->'Competitors') as test
FROM public."Competitions" WHERE public."Competitions"."Data" @> '{"CompetitionData":{"Competitors":[{"Shoes":{"Brand":"Nike"}}]}}';

是否可以只将鞋类品牌“ Nike”的竞争对手归还?

2 个答案:

答案 0 :(得分:2)

在from子句中使用jsonb_array_elements

SELECT j.* FROM
t cross join lateral 
  jsonb_array_elements(data->'CompetitionData'->'Competitors') as j(comp)
where j.comp->'Shoes'->>'Brand' = 'Nike'

Demo

答案 1 :(得分:0)

为什么要将其保存在jsonb中?只需将其标准化到数据库中即可:

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