gpt4 book ai didi

sql - Postgresql插入多行选择

转载 作者:行者123 更新时间:2023-11-29 13:48:44 24 4
gpt4 key购买 nike

我正在创建一个程序来解析输入的 json 数据并将其存储在表中。该函数如下所示:

create or replace function test_func(d json)
returns void as $$
begin
with n as (
insert into t1 (name) values (d::json -> 'name') returning id
), c as (
insert into t2 (cars) values json_array_elements_text(d::json -> 'cars') returning id
)
insert into t3 (id, name_id, cars_id, brand)
select 1, n.id, c.id, json_array_elements_text(d::json -> 'brands') from n, c;
end;
$$ language plpgsql;


CREATE TABLE t1
(
"id" SERIAL PRIMARY KEY,
"name" text NOT NULL
)

CREATE TABLE t2
(
"id" SERIAL PRIMARY KEY,
"cars" text NOT NULL,
"car_type" int
)

CREATE TABLE t3
(
"id" int,
"name_id" int REFERENCES t1(id),
"cars_id" int REFERENCES t2(id),
"brand" text
)

数据输入的名称是文本,汽车和品牌是数组,全部包装在一个 json 中。所以最后一个插入有混合值类型,如果这个人有两辆车,我有 4 行插入到 t3 因为 c.id 和 json_array_elements_text(d::json -> 'brands') 都有两个数据集,2x2 = 4,如何将插入的值一对一映射?所以第一个 c.id 应该映射到第一个品牌。

最佳答案

要映射它们,您必须在不同的行而不是真实的行上加入。

这里是如何在 id with ordinality 上加入两者的例子 - 希望它会有所帮助。基于你的 json 样本

t=# with j as (select '{"name":"john", "cars":["bmw X5 xdrive","volvo v90 rdesign"], "brands":["bmw","volvo"]}'::json d)
select car,brand,t1.id from j
join json_array_elements_text(j.d->'cars') with ordinality t1(car,id) on true
join json_array_elements_text(j.d->'brands') with ordinality t2(brand,id) on t1.id = t2.id
;
car | brand | id
-------------------+-------+----
bmw X5 xdrive | bmw | 1
volvo v90 rdesign | volvo | 2
(2 rows)

更新 详细说明 OP:

您可以通过聚合 em 然后使用索引来避免映射多行:

您的姓名:

create or replace function test_func(d json)
returns void as $$
begin
with j as (select d)
, a as (
select car,brand,t1.id oid
from j
join json_array_elements_text(j.d->'cars') with ordinality t1(car,id) on true
join json_array_elements_text(j.d->'brands') with ordinality t2(brand,id) on t1.id = t2.id
)
, n as (
insert into t1 (name) values (d::json -> 'name') returning id
), c as (
insert into t2 (cars) select car from a order by oid returning id
)
, ag as (
select array_agg(c.id) cid from c
)
insert into t3 (id, name_id, cars_id, brand)
select 1, n.id,cid[oid], brand
from a
join n on true
join ag on true
;
end;
$$ language plpgsql;

您的表:

CREATE TABLE t1 ( "id" SERIAL PRIMARY KEY, "name" text NOT NULL );
CREATE TABLE t2 ( "id" SERIAL PRIMARY KEY, "cars" text NOT NULL );
CREATE TABLE t3 ( "id" int, "name_id" int REFERENCES t1(id), "cars_id" int REFERENCES t2(id), "brand" text );

执行:

t=#   select test_func('{"name":"john", "cars":["bmw X5 xdrive","volvo v90 rdesign"], "brands":["bmw","volvo"]}');
test_func
-----------

(1 row)

t=# select * from t1;
id | name
----+--------
14 | "john"
(1 row)

t=# select * from t2;
id | cars
----+-------------------
27 | bmw X5 xdrive
28 | volvo v90 rdesign
(2 rows)

t=# select * from t3;
id | name_id | cars_id | brand
----+---------+---------+-------
1 | 14 | 27 | bmw
1 | 14 | 28 | volvo
(2 rows)

关于sql - Postgresql插入多行选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44316707/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com