PostgreSQL: обновить целевую таблицу из другой таблицы на основе объединенного столбца

#sql #postgresql #sql-update #inner-join

#sql #postgresql #sql-обновление #внутреннее соединение

Вопрос:

Мне нужно обновить table3 из table1, используя объединенный столбец из table2 в PostreSQL, я могу придумать общее табличное выражение для его достижения, но, похоже, это не выполняется.

 A>existing target data **table3**

col1 code  uid 
A     123  abc
B     123  cef

B>lookup table data **table2**

id uid 
4  abc
5  cef
4  klm 
5  mnp 


C>new data in stage **table1**

col1  code  uid 
C     123   klm
D     123   mnp

D>result final target data **table3** (updated with table1)

col1  code  uid 
C     123   abc
D     123   def
  

Объяснение :-

uid из table3 просматривается в table2, который создает данные после объединения как

 code id col1
123  4  A
123  5  B
  

Теперь этап table1 просматривается в table2 для создания данных после объединения как

 code id col1
123  4  C
123  5  D
  

и, следовательно, на основе кода первичных ключей id значение col1 обновляется до

 col1  code  uid 
C     123   abc
D     123   def
  

Пробовал код SQL

 with 
  sm as 
    (
     select 
     s.col1
    ,s.code
    ,ssi.id from stage.table3 s 
     join stage.table2 ssi on s.uid = ssi.uid ),
  cte as (
     select 
     k.col1
    ,k.code
    ,ss.id 
     from stage.table1 k
     join stage.table2 ss on k.uid = ss.uid )
  update sm set col1 = cte.col1 
  from cte where 
  cte.id = sm.id and cte.code = sm.code;
  

DDL для тестовых данных

 create table table3(col1, code, uid) as 
(
select 'A',123,'abc'
union all 
select 'B', 123,'cef'
);


create table table2(id,uid) as 
(
select 4,'abc'
union all 
select 5,'cef'
union all 
select 4,'klm'
union all 
select 5,'mnp'
);


create table table1(col1, code, uid) as 
(
select 'C',123,'klm'
union all 
select 'D',123,'mnp'
);
  

Пожалуйста, обратите внимание: — целевая таблица3 не имеет столбца id, он должен быть получен путем присоединения к таблице2 на основе uid.

Ценю вашу помощь в этом

ПРАВКИ

Я попытался переписать запрос, как показано ниже, и он работает. Любые комментарии и предложения приветствуются.

Решение

 update table3 sm
set col1 = p.col1
from table1 p  -- join stage table to lookup table to retrieve id
join table2 ss on p.uid = ss.uid 
where exists 
(select from table3 smi    -- join target table to lookup table to retrieve id
join table2 ssi on smi.uid = ssi.uid 
where  -- filter and join both 
ss.id = ssi.id and 
sm.code = smi.code and 
sm.uid = smi.uid and
sm.code = p.code
);
  

Комментарии:

1. Отредактируйте свой вопрос и предоставьте примеры данных, желаемые результаты и четкое объяснение того, чего вы хотите достичь.

2. @GordonLinoff, попытался сделать вопрос более описательным, имеет ли это смысл?

3. Я смог получить решение, переформулировав запрос, как указано в описании

Ответ №1:

я думаю, что логика, которую вы хотите:

 update table3 t3
set col1 = t1.col1
from table1 t1
inner join table2 t2 on t2.uid = t1.uid
where t3.id = t2.id
  

Комментарии:

1. Спасибо за ответ, но в таблице 3 нет столбца id, он должен быть получен путем объединения из таблицы2, возможно ли это приспособить или я что-то пропустил

Ответ №2:

Предполагая, что table2.id это уникальный или первичный ключ, тогда я думаю, что логика:

 update stage.table3 s 
    set s.col1 = 
    from stage.table2 ssi join
         stage.table1 k
         on k.uid = ss.uid 
    where s.uid = ssi.uid;
  

Я скажу, что было бы намного проще определить правильный запрос на основе выборочных данных и описания того, что вы хотите сделать. Пример кода на самом деле не особенно полезен.

Комментарии:

1. добавлено объяснение и желаемый результат