在 postgres 中合并
Merge in postgres
我正在尝试将以下 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));
请注意,这对于并发执行 NOT 是安全的(Oracle 的 MERGE 语句也不是)。您仍然可以在 table1 中得到重复值(关于 (sgr,cdd)
的组合)。
防止重复的唯一明智方法是创建唯一索引(或约束)- 这将使您能够使用更高效的 insert on conflict
。如果您的业务规则不允许重复,您应该确实考虑一下。
请注意,我将 WHERE 子句中古老的隐式连接转换为现代的显式 JOIN
运算符,但这并不是工作所必需的。
我正在尝试将以下 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));
请注意,这对于并发执行 NOT 是安全的(Oracle 的 MERGE 语句也不是)。您仍然可以在 table1 中得到重复值(关于 (sgr,cdd)
的组合)。
防止重复的唯一明智方法是创建唯一索引(或约束)- 这将使您能够使用更高效的 insert on conflict
。如果您的业务规则不允许重复,您应该确实考虑一下。
请注意,我将 WHERE 子句中古老的隐式连接转换为现代的显式 JOIN
运算符,但这并不是工作所必需的。