Eva*_*oll 4 sql-server insert update upsert
所有语法都是有效的 PostgreSQL 作为 UPSERT 的示例,它返回字段的旧值和新值。比方说,我有一个表foo用(1,A)...(5,E)。
CREATE TEMP TABLE foo
AS
SELECT id, chr(id+64)
FROM generate_series(1,5) AS t(id);
CREATE UNIQUE INDEX ON foo(id);
id | chr
----+-----
1 | A
2 | B
3 | C
4 | D
5 | E
(5 rows)
Run Code Online (Sandbox Code Playgroud)
现在,假设我想要 UPSERT 6 行。一些碰撞,一些新的行。
SELECT id, chr(id+74)
FROM generate_series(3,8) AS t(id);
id | chr
----+-----
3 | M
4 | N
5 | O
6 | P
7 | Q
8 | R
Run Code Online (Sandbox Code Playgroud)
我怎么得到,
idchrchr在 PostgreSQL 中,我会做..
WITH t1 AS (
SELECT id, foo.chr AS oldchr, chr(id+74)
FROM generate_series(3,8) AS t(id)
LEFT OUTER JOIN foo USING (id)
),
tupdate AS (
UPDATE foo
SET chr = t1.chr
FROM t1
WHERE foo.id = t1.id
RETURNING foo.id, t1.chr, t1.oldchr
),
tinsert AS (
INSERT INTO foo (id, chr)
SELECT id, chr
FROM t1
WHERE t1.oldchr IS NULL
RETURNING id, chr, null::text
)
SELECT * FROM tupdate
UNION ALL
SELECT * FROM tinsert;
id | chr | oldchr
----+-----+--------
3 | M | C
4 | N | D
5 | O | E
6 | P |
7 | Q |
8 | R |
(6 rows)
Run Code Online (Sandbox Code Playgroud)
上表由这些 CTE 返回。而且,这就是我正在寻找的输出。
温度表:
create table #foo
(
id int unique,
chr char(1)
);
insert into #foo(id, chr) values
(1, 'A'),
(2, 'B'),
(3, 'C'),
(4, 'D'),
(5, 'E');
Run Code Online (Sandbox Code Playgroud)
合并:
with t1 as
(
select T.id,
T.chr
from (values (3, 'M'),
(4, 'N'),
(5, 'O'),
(6, 'P'),
(7, 'Q'),
(8, 'R')) as T(id, chr)
)
merge #foo as T
using t1 as S
on T.id = S.id
when not matched then
insert (id, chr) values(S.id, S.chr)
when matched then
update set chr = S.chr
output inserted.id,
inserted.chr,
deleted.chr as oldchr;
Run Code Online (Sandbox Code Playgroud)
结果:
id chr oldchr
----------- ---- ------
3 M C
4 N D
5 O E
6 P NULL
7 Q NULL
8 R NULL
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1505 次 |
| 最近记录: |