Выполните UNNEST, INNER JOIN, а затем ARRAY_AGG как часть запроса UPDATE. - PullRequest
1 голос
/ 27 марта 2020

Я пытаюсь удалить массив из одной таблицы, используя ORDINALITY для сохранения порядка, затем выполнить INNER JOIN для другой таблицы, чтобы найти соответствующее значение из указанного столбца c, а затем использовать ARRAY_AGG, чтобы упаковать эту резервную копию и выполнить UPDATE. оригинальный стол. У меня что-то работает для одного запроса, но я хочу сделать ОБНОВЛЕНИЕ для каждой строки в таблице, но не могу заставить его работать. Я чувствую, что я близок, но я трачу слишком много времени на это, поэтому любая помощь будет оценена.

Ниже приведен код для генерации таблиц, а также ответ, который я ищу, и мои попытки.

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;

Но когда Я пытаюсь сделать что-то похожее на ОБНОВЛЕНИЕ каждой строки в таблице, я делаю что-то не так. Я пробовал следующее, но это не работает:

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

Если кто-нибудь может указать мне правильное направление, я был бы очень благодарен.

Спасибо

1 Ответ

0 голосов
/ 27 марта 2020

Вы можете превратить ваш существующий запрос в CTE и объединить его с исходной таблицей для обновления:

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

Демонстрация на БД Fiddle - таблица содержимое после 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

)

Демонстрация на DB Fiddle

...