执行 UNNEST、INNER JOIN,然后 ARRAY_AGG 作为 UPDATE 查询的一部分
Perform UNNEST, INNER JOIN and then ARRAY_AGG as part of an UPDATE query
我正在尝试使用 ORDINALITY 从一个 table 中取消嵌套数组以保持顺序,然后在另一个 table 上执行 INNER JOIN 以从特定列中找到相应的值,然后使用 ARRAY_AGG 打包备份并更新原始 table。我有一些东西可以用于单个查询,但我想对 table 中的每一行进行更新,但似乎无法让它工作。我觉得我很接近,但我在这上面花的时间太长了,所以我们将不胜感激。
下面是生成 table 的代码,以及我正在寻找的答案和我的尝试。
create table table_1(
table_1_id int,
table_2_id_list int[],
table_2_geom text[]
);
insert into table_1 values
(1, ARRAY[1,3,5], null) ,(2, ARRAY[2,4,6], null);
create table table_2(table_2_id int, geom text);
insert into table_2 values
(1, 'geom1'), (2, 'geom2'), (3, 'geom3'),
(4, 'geom4'), (5, 'geom5'), (6, 'geom6');
我想这样结束:
table_1_id | table_2_id_list | table_2_geom
------------------------------------------------------------------
1 | (1, 3, 5) | (geom1, geom3, geom5)
2 | (2, 4, 6) | (geom2, geom4, geom6)
我可以使用以下方法使其适用于单个案例:
SELECT
TABLE_1_ID,
array_agg(TABLE_2.geom ORDER BY ORDINALITY)
FROM TABLE_1,
unnest(table_2_id_list) WITH ORDINALITY a
INNER JOIN TABLE_2 ON a = TABLE_2.TABLE_2_ID
GROUP BY TABLE_1_ID LIMIT 1;
但是当我尝试对 table 中的每一行进行更新时,我做错了。我已经尝试了以下但它不起作用:
UPDATE TABLE_1
SET table_2_geom = (
SELECT array_agg(TABLE_2.geom ORDER BY ORDINALITY)
FROM TABLE_1,
unnest(table_2_id_list) WITH ORDINALITY a
INNER JOIN TABLE_2 ON a = TABLE_2.TABLE_2_ID
);
如果有人能指出正确的方向,我将不胜感激。
谢谢
您可以将现有查询转换为 CTE,然后将其与原始 table 合并以进行更新:
with cte as (
select
t1.table_1_id,
array_agg(t2.geom order by ordinality) table_2_geom
from
table_1 t1
cross join lateral unnest(t1.table_2_id_list) with ordinality i(table_2_id)
inner join table_2 t2 on t2.table_2_id = i.table_2_id
group by t1.table_1_id
)
update table_1 t1
set table_2_geom = c.table_2_geom
from cte c
where c.table_1_id = t1.table_1_id
Demo on DB Fiddle - table update
后的内容:
table_1_id | table_2_id_list | table_2_geom
---------: | :-------------- | :------------------
1 | {1,3,5} | {geom1,geom3,geom5}
2 | {2,4,6} | {geom2,geom4,geom6}
但是相关子查询可能更简单:
update table_1 t1
set table_2_geom = (
select array_agg(t2.geom order by ordinality)
from unnest(t1.table_2_id_list) with ordinality i(table_2_id)
inner join table_2 t2 on t2.table_2_id = i.table_2_id
)
我正在尝试使用 ORDINALITY 从一个 table 中取消嵌套数组以保持顺序,然后在另一个 table 上执行 INNER JOIN 以从特定列中找到相应的值,然后使用 ARRAY_AGG 打包备份并更新原始 table。我有一些东西可以用于单个查询,但我想对 table 中的每一行进行更新,但似乎无法让它工作。我觉得我很接近,但我在这上面花的时间太长了,所以我们将不胜感激。
下面是生成 table 的代码,以及我正在寻找的答案和我的尝试。
create table table_1(
table_1_id int,
table_2_id_list int[],
table_2_geom text[]
);
insert into table_1 values
(1, ARRAY[1,3,5], null) ,(2, ARRAY[2,4,6], null);
create table table_2(table_2_id int, geom text);
insert into table_2 values
(1, 'geom1'), (2, 'geom2'), (3, 'geom3'),
(4, 'geom4'), (5, 'geom5'), (6, 'geom6');
我想这样结束:
table_1_id | table_2_id_list | table_2_geom
------------------------------------------------------------------
1 | (1, 3, 5) | (geom1, geom3, geom5)
2 | (2, 4, 6) | (geom2, geom4, geom6)
我可以使用以下方法使其适用于单个案例:
SELECT
TABLE_1_ID,
array_agg(TABLE_2.geom ORDER BY ORDINALITY)
FROM TABLE_1,
unnest(table_2_id_list) WITH ORDINALITY a
INNER JOIN TABLE_2 ON a = TABLE_2.TABLE_2_ID
GROUP BY TABLE_1_ID LIMIT 1;
但是当我尝试对 table 中的每一行进行更新时,我做错了。我已经尝试了以下但它不起作用:
UPDATE TABLE_1
SET table_2_geom = (
SELECT array_agg(TABLE_2.geom ORDER BY ORDINALITY)
FROM TABLE_1,
unnest(table_2_id_list) WITH ORDINALITY a
INNER JOIN TABLE_2 ON a = TABLE_2.TABLE_2_ID
);
如果有人能指出正确的方向,我将不胜感激。
谢谢
您可以将现有查询转换为 CTE,然后将其与原始 table 合并以进行更新:
with cte as (
select
t1.table_1_id,
array_agg(t2.geom order by ordinality) table_2_geom
from
table_1 t1
cross join lateral unnest(t1.table_2_id_list) with ordinality i(table_2_id)
inner join table_2 t2 on t2.table_2_id = i.table_2_id
group by t1.table_1_id
)
update table_1 t1
set table_2_geom = c.table_2_geom
from cte c
where c.table_1_id = t1.table_1_id
Demo on DB Fiddle - table update
后的内容:
table_1_id | table_2_id_list | table_2_geom ---------: | :-------------- | :------------------ 1 | {1,3,5} | {geom1,geom3,geom5} 2 | {2,4,6} | {geom2,geom4,geom6}
但是相关子查询可能更简单:
update table_1 t1
set table_2_geom = (
select array_agg(t2.geom order by ordinality)
from unnest(t1.table_2_id_list) with ordinality i(table_2_id)
inner join table_2 t2 on t2.table_2_id = i.table_2_id
)