postgresql - 在 postgres 中合并

标签 postgresql database-migration postgresql-9.5

我正在尝试将以下 oracle 查询转换为 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;

但我怀疑,如果数据匹配,我的 oracle 查询不会更新任何列,但无法相应地转换它。谁能帮我更正一下?

最佳答案

假设您在 (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 语句也不是)。您仍然可以在 table1 中得到重复值(关于 (sgr,cdd) 的组合)。

防止重复的唯一明智方法是创建唯一索引(或约束)- 这将使您能够使用更高效的insert on conflict。如果您的业务规则不允许重复,您应该真正考虑这一点。


请注意,我将 WHERE 子句中古老的隐式连接转换为现代的显式 JOIN 运算符,但这并不是工作所必需的。

关于postgresql - 在 postgres 中合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52497478/

相关文章:

postgresql创建函数

php - 使用 phinx 迁移库在非主键列上自动递增

json - 如何将 to_jsonb 用作 row_to_jsonb?关于 "how much"的详细信息在哪里?

php - 数据迁移查询

c# - 数据库中已经有一个名为 '__MigrationHistory' 的对象

postgresql - Postgres 9.5.0 中的 ON CONFLICT 语法错误

jsonb_agg : Avoid objects wrapped with "jsonb_build_object"

c# - EF Core - 无法添加具有相同相关对象的实体

sql - 您如何为 Amazon redshift 数据库编写查询,以便相关查询的 where 子句具有两个条件?

ruby - 连接到单独 AWS 实例上的 PostGres 数据库时出现 "could not receive data from server: Connection timed out"或 "connection not open"错误