我有以下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”的竞争对手归还?
答案 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'
答案 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';