PostgreSQL:如果不存在,则插入;如果不存在,则返回ID

时间:2020-09-09 18:18:04

标签: sql postgresql

以下查询将插入IP地址(如果没有)并返回ID。

WITH variables AS (
  SELECT '1.1.1.2'::inet AS ip
)
INSERT INTO globals.ips (ip)
SELECT v.ip
FROM variables AS v
WHERE NOT EXISTS (
    SELECT i.global_ip_id 
    FROM globals.ips AS i 
    WHERE i.ip = v.ip
)
RETURNING global_ip_id

但是,当值已经存在于数据库中时,它不会返回ID。

值已经存在时,如何获取ID?


我正在运行PostgreSQL 12。

2 个答案:

答案 0 :(得分:0)

WITH variables AS (
  SELECT '1.1.1.2'::inet AS ip
), wt0 as (
INSERT INTO globals.ips (ip)
SELECT v.ip
FROM variables AS v
WHERE NOT EXISTS (
    SELECT i.global_ip_id 
    FROM globals.ips AS i 
    WHERE i.ip = v.ip
)
RETURNING global_ip_id
)
SELECT global_ip_id FROM wt0
UNION
SELECT id FROM globals.ips WHERE ip = 'SOMETHING';

答案 1 :(得分:0)

我不确定它是否最优雅;但每次都会返回IP的ID。 而且我只需要输入一次IP。

WITH v AS (
   SELECT '1.1.1.110'::inet AS ip
), i AS (
    INSERT INTO globals.ips (ip)
    SELECT * FROM v
    WHERE NOT EXISTS (
        SELECT i.global_ip_id
        FROM globals.ips AS i
        WHERE i.ip = v.ip
    )
    RETURNING global_ip_id
)
SELECT global_ip_id FROM i
UNION ALL
SELECT global_ip_id FROM globals.ips g
LEFT JOIN v ON g.ip = v.ip
WHERE g.ip = v.ip
LIMIT 1;

如果有人对如何改善此问题有任何建议,请告诉我。


更优雅的解决方案:

INSERT INTO globals.ips (ip) VALUES ('1.1.1.1'::inet)
ON CONFLICT (ip) DO UPDATE SET ip = EXCLUDED.ip
RETURNING global_ip_id AS id;

但是,比原来的要慢一些。

相关问题