在我的 Postgres 数据库中,我天真地在表
Foos
中创建了一列作为 json[]
,如下所示:
TABLE Foos
id | ... | baas
--------------------------------
1 | ... | [
| ... | {
| ... | "name": "a",
| ... | "property": "1",
| ... | },
| ... | {
| ... | "name": "b",
| ... | "property": "2",
| ... | },
| ... | ...
| ... | ]
2 | ... | [ ... ]
3 | ... | [ ... ]
现在我想用 json 数组中的项目填充表
Baas
,如下所示:
TABLE Baas
id | foo_id | name | property
------------------------------
1 | 1 | a | 1
2 | 1 | b | 2
如何用简单的 SQL 来做到这一点?
我自己解决了:
INSERT INTO public.baas (foo_id, name, property)
SELECT
foo_id,
array_element ->> 'name',
(array_element ->> 'property')::integer
FROM (
SELECT
id as foo_id,
unnest(baas) AS array_element
FROM
public.foos
) AS subquery_alias;
json_populate_record()
或 json_populate_recordset()
。但是要搞清楚你的设置和术语!
json[]
是 json
的 Postgres 数组。虽然这是完全可能的,但可能性不大。使用 JSON 后,通常会将 JSON 数组嵌套在普通 Postgres 类型中 json
。json[]
:Postgres json 数组 - 不太可能设置:
CREATE TABLE foos (
id int
, baas json[] -- type json[] - Postgres array of json (??)
);
INSERT INTO foos VALUES
(1, '{"{\"name\": \"a1\", \"property\": \"1\"}"
,"{\"name\": \"b1\", \"property\": \"2\"}"}') -- pg array with 2 json elements: JSON objects with two properites each
, (2, '{"[{\"name\": \"a2\", \"property\": \"1\"}
,{\"name\": \"b2\", \"property\": \"2\"}]"}') -- pg array with 1 json element: JSON array with 2 objects each, two properites each
;
其中一个查询就可以完成这项工作:
INSERT INTO baas (foo_id, name, property)
SELECT f.id, b.name, b.property
FROM foos f, unnest(f.baas) a(baas), json_populate_record(null::baas, a.baas) b
WHERE f.id = 1;
INSERT INTO baas (foo_id, name, property)
SELECT f.id, b.name, b.property
FROM foos f, unnest(f.baas) a(baas), json_populate_recordset(null::baas, a.baas) b
WHERE f.id = 2;
json
:带有嵌套 JSON 数组的标量类型 - 更有可能!设置:
-- DROP TABLE IF EXISTS foos;
CREATE TEMP TABLE foos (
id int
, baas json -- type json (with nested JSON array)
);
INSERT INTO foos VALUES
(3, '[{"name": "a", "property": "1"}
, {"name": "b", "property": "2"}]') -- 1 JSON array with 2 objects, each with 2 properties
;
查询:
INSERT INTO baas (foo_id, name, property)
SELECT f.id, b.name, b.property
FROM foos f, json_populate_recordset(null::baas, f.baas) b;