Оставить присоединиться к обновлению - PullRequest
0 голосов
/ 17 октября 2018

Мне не удалось найти простое обновление таблицы со значением из левого соединения.Я хочу сделать что-то вроде этого:

UPDATE tbl1 p
LEFT JOIN (
select column1 , column2 from tbl2
union
select column1,column2 from tbl3
) c on c.column2=p.column2
SET p.column1 =  nvl(c.column1, 'dummy');

Ответы [ 5 ]

0 голосов
/ 20 октября 2018

Оператор слияния мог бы быть идеальным решением, если бы можно было обновить одно и то же поле в WHEN MATCHED и в WHEN NOT MATCHED.В любом случае я исправил это так: таблица заполняется из внешней таблицы с помощью процедуры.Устанавливая поле 'dummy' для всех записей в операторе вставки процедуры и используйте только MERGE WHEN MATCHED после работ, как я ожидал

PS: я не мог заставить его работать, как сказал @ Ondřej Crha.

0 голосов
/ 17 октября 2018

Использование merge:

merge into tbl1 tgt
using (select min(column1) column1, column2
         from (select column1, column2 from tbl2 union all
               select column1, column2 from tbl3)
         group by column2) src
on (tgt.column2 = src.column2)
when matched then update set tgt.column1 = src.column1

Допустим, у вас есть эти таблицы:

create table tbl1(column1, column2) as (
    select 0, 'A' from dual union all
    select 0, 'B' from dual union all
    select 0, 'C' from dual union all
    select 0, 'D' from dual );

create table tbl2(column1, column2) as (
    select  1, 'A' from dual union all
    select 41, 'D' from dual );  

create table tbl3(column1, column2) as (
    select  2, 'B' from dual union all
    select 42, 'D' from dual );  

У нас есть значение для ключа A в tbl2, значение для B в tbl3 значение для C отсутствует в обеих исходных таблицах, и у нас есть два проблемных значения для ключа D.Вы должны решить, что делать в последнем случае, использовать любую функцию агрегирования, например min(), avg() или listagg() для строк.Если такая ситуация невозможна, вы можете упростить мое утверждение, заменив исходный подзапрос простым объединением.

Вы также можете использовать update, но в этом случае вы должны добавить предложение where и проверить наличие ключей, чтобы избежать обнуления значений, и это удлиняет код.

Результат merge:

   COLUMN1  COLUMN2
----------  -------
         1  A
         2  B
         0  C
        41  D
0 голосов
/ 17 октября 2018

Я бы порекомендовал выразить это как:

UPDATE tbl1 p
    SET p.column1 =  COALESCE((SELECT column1 from tbl2 t2 WHERE t2.column2 = p.column2),
                              (SELECT column1 from tbl3 t3 WHERE t3.column2 = p.column2),
                              'dummy'
                             );

Каждый подзапрос может использовать индексы, поэтому он также должен иметь лучшую производительность.

0 голосов
/ 17 октября 2018

Попробуйте и посмотрите, дает ли приведенный ниже код производительность с CTE

Update tbl1 p
set column1 =  nvl((with CTE as 
(select column1 , column2 from tbl2
union
select column1,column2 from tbl3) select column1 from CTE where CTE.column2= p.column2  ),'dummy');
0 голосов
/ 17 октября 2018
UPDATE p SET p.column1 =  nvl(c.column1, 'dummy')
from tbl1 p
LEFT JOIN (
select column1 , column2 from tbl2
union
select column1,column2 from tbl3
) c on c.column2=p.column2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...