Der*_*ler 22 postgresql upsert postgresql-9.5
我有一个tag包含 2 列的表:id(uuid) 和name(text)。我现在想在表中插入一个新标签,但如果该标签已经存在,我只想获取id现有记录的 。
我以为我可以ON CONFLICT DO NOTHING结合使用RETURNING "id":
INSERT INTO
"tag" ("name")
VALUES( 'foo' )
ON CONFLICT DO NOTHING
RETURNING "id";
Run Code Online (Sandbox Code Playgroud)
但是,如果名称为“foo”的标签已经存在,则会返回一个空的结果集。
然后我将查询更改为使用 noopDO UPDATE子句:
INSERT INTO
"tag" ("name")
VALUES( 'foo' )
ON CONFLICT ("name") DO UPDATE SET "name" = 'foo'
RETURNING "id";
Run Code Online (Sandbox Code Playgroud)
这按预期工作,但有点令人困惑,因为我只是将名称设置为已经存在的值。
这是解决这个问题的方法还是我缺少更简单的方法?
ype*_*eᵀᴹ 12
这将在所有 3 种情况下(据我测试)都有效,如果要插入的值都是新的或已经在表中或混合:
WITH
val (name) AS
( VALUES -- rows to be inserted
('foo'),
('bar'),
('zzz')
),
ins AS
( INSERT INTO
tag (name)
SELECT name FROM val
ON CONFLICT (name) DO NOTHING
RETURNING id, name -- only the inserted ones
)
SELECT COALESCE(ins.id, tag.id) AS id,
val.name
FROM val
LEFT JOIN ins ON ins.name = val.name
LEFT JOIN tag ON tag.name = val.name ;
Run Code Online (Sandbox Code Playgroud)
可能还有其他一些方法可以做到这一点,也许不使用新ON CONFLICT语法。
| 归档时间: |
|
| 查看次数: |
13221 次 |
| 最近记录: |