Слияние в postgres - PullRequest
       17

Слияние в postgres

0 голосов
/ 25 сентября 2018

Я пытаюсь преобразовать приведенный ниже запрос оракула в postgres,

MERGE INTO table1 g
USING (SELECT distinct g.CDD , d.SGR
from  table2 g, table3 d
where g.IDF = d.IDF) f
ON (g.SGR = f.SGR and g.CDD = f.CDD)
   WHEN NOT MATCHED THEN
   INSERT (SGR, CDD)
   VALUES (f.SGR, f.CDD);

Я внес следующие изменения, совместимые с postgres:

WITH f AS (
SELECT distinct g.CDD , d.SGR
from  table2 g, table3 d
where g.IDF = d.IDF
),
upd AS (
update table1 g 
set 
SGR = f.SGR , CDD = f.CDD 
FROM f where g.SGR = f.SGR  and g.CDD = f.CDD  
returning g.CDD, g.SGR
)
INSERT INTO table1(SGR, CDD ) SELECT f.SGR, f.CDD FROM f;

Но сомнительно, мой запрос оракула не обновляетсялюбые столбцы, если данные совпадают, но я не могу соответствующим образом преобразовать их.Кто-нибудь может мне помочь исправить это?

1 Ответ

0 голосов
/ 25 сентября 2018

При условии, что у вас есть первичный (или уникальный) ключ на (sgr, cdd), вы можете преобразовать его в оператор insert ... on conflict:

insert into table1 (SGR, CDD)
select  distinct g.CDD, d.SGR
from table2 g
  join table3 d ON g.IDF = d.IDF
on conflict (cdd, sgr) do nothing;

Если у вас нет уникального ограничения (в связи с этим возникает вопрос: почему?) тогда должен работать прямой оператор INSERT ... SELECT (что также могло бы ухудшить работу Oracle).

WITH f AS (
   SELECT distinct g.CDD, d.SGR
   from table2 g
     join table3 d on g.IDF = d.IDF
)
INSERT INTO table1 (SGR, CDD) 
SELECT f.SGR, f.CDD 
FROM f
WHERE NOT EXISTS (select *
                  from table1 t1
                     join f on (t1.sgr, t1.cdd) = (f.cdd, f.sgrf));

Обратите внимание, что это НЕ безопасно для одновременного выполнения (и ни один из операторов Oracle MERGE).Вы все еще можете получить дубликаты значений в таблице1 (в отношении комбинации (sgr,cdd)).

Единственный разумный способ предотвратить дублирование - это создать уникальный индекс (или ограничение), который позволит вам использовать гораздо более эффективный insert on conflict.Вы должны действительно учитывать, что если ваши бизнес-правила запрещают дублирование.


Обратите внимание, что я преобразовал ваше древнее неявное объединение в предложении WHERE в современный явный оператор JOIN,но это не обязательно, чтобы это работало.

...