首页 > 解决方案 > 在非连续 ID 中插入结果

问题描述

我有以下查询:

INSERT INTO hosts (name, domain, ip)
SELECT name, domain, ip
FROM staging_hosts
ON CONFLICT (ip) DO UPDATE
SET name = excluded.name, domain = excluded.domain;

除了我的“主机”表中的 ID 没有按顺序递增的事实之外,它工作正常。例如,运行此查询后,我将获得以下新 ID:

114855
114859
114873
114977
117389
115326

hosts 表上的 ID 列是串行的,所以我不确定为什么 ID 会按顺序递增。

标签: postgresql

解决方案


如果您坚持最小化差距,您可以这样做,包括示例表:

CREATE TABLE foo (
  id SERIAL PRIMARY KEY,
  ip INT,
  name TEXT,
  UNIQUE(ip) );

CREATE TABLE staging (
  ip INT,
  name TEXT );

INSERT INTO foo (ip,name) VALUES (1,'hello'),(2,'abc'),(10,'world');
INSERT INTO staging VALUES (1,'byebye'),(2,'def'),(11,'world');

WITH s AS ( 
    SELECT COALESCE( foo.id, nextval('foo_id_seq'::regclass)) AS id, 
    staging.ip,staging.name
    FROM staging LEFT JOIN foo USING (ip))
INSERT INTO foo (id,ip,name) SELECT * FROM s
ON CONFLICT(id) DO UPDATE 
SET ip=excluded.ip, name=excluded.name;

如果不需要,COALESCE 不会评估第二个参数,这意味着它只在需要时调用 nextval。


推荐阅读