插入新行并获取主键或获取现有记录的主键

时间:2014-05-07 17:18:02

标签: sql postgresql postgresql-9.3

我在Postgres 9.3中有一个简单的标签表:

CREATE TABLE tag (
  id SERIAL PRIMARY KEY,
  text TEXT NOT NULL UNIQUE
);

目前我可以插入新标签并轻松取回新ID:

INSERT INTO tag (text) VALUES ('hey') RETURNING id

但是我想检查标签是否已经存在(唯一约束),如果确实存在,则返回现有标签的id。

我尝试使用COALESCE来实现这一目标:

SELECT COALESCE(
    (SELECT id FROM tag WHERE text='hey'),
    (INSERT INTO tag (text) VALUES ('hey') RETURNING id)
)

但不幸的是,虽然我认为这种逻辑是合理的,但我看起来并不像INSERT中的COALESCE语句(在INTO生成语法错误)。

最简单的方法是什么?

2 个答案:

答案 0 :(得分:0)

这应该会给你相同的结果。如果该行不存在,则创建它。该部分执行后,该行肯定会存在,我们选择它的id。

IF NOT EXISTS (SELECT id FROM tag WHERE text = 'hey')
BEGIN
    INSERT INTO tag (text) VALUES ('hey')
END
SELECT id FROM tag WHERE text = 'hey'

答案 1 :(得分:0)

Clodoaldo Neto answer的信用转入{{3}}。

我在这里回答是因为虽然他的回答确实指向了我的方向略有不同,但我已经简化了一点。

WITH 
    existing AS (SELECT id FROM tag WHERE text='hey'),
    new AS (INSERT INTO tag (text) SELECT 'hey' WHERE NOT EXISTS (SELECT 1 FROM existing) RETURNING id)

SELECT id FROM existing UNION ALL SELECT id FROM new