我在使用Postgres 9.5中的新UPSERT功能时遇到问题
我有一个表,用于汇总来自另一个表的数据。复合键由20列组成,其中10列可以为空。下面,我为我遇到的问题创建了一个较小的版本,尤其是NULL值。
CREATE TABLE public.test_upsert (
upsert_id serial,
name character varying(32) NOT NULL,
status integer NOT NULL,
test_field text,
identifier character varying(255),
count integer,
CONSTRAINT upsert_id_pkey PRIMARY KEY (upsert_id),
CONSTRAINT test_upsert_name_status_test_field_key UNIQUE (name, status, test_field)
);
根据需要运行此查询(首先插入,然后随后的插入仅增加计数):
INSERT INTO test_upsert as tu(name,status,test_field,identifier, count)
VALUES ('shaun',1,'test value','ident', 1)
ON CONFLICT (name,status,test_field) DO UPDATE set count = tu.count + 1
where tu.name = 'shaun' AND tu.status = 1 AND tu.test_field = 'test value';
但是,如果我运行此查询,则每次插入1行,而不是增加初始行的计数:
INSERT INTO test_upsert as tu(name,status,test_field,identifier, count)
VALUES ('shaun',1,null,'ident', 1)
ON CONFLICT (name,status,test_field) DO UPDATE set count = tu.count + 1
where tu.name = 'shaun' AND tu.status = 1 AND tu.test_field = null;
这是我的问题。我只需要简单地增加计数值,而不用空值创建多个相同的行。
尝试添加部分唯一索引:
CREATE UNIQUE INDEX test_upsert_upsert_id_idx
ON public.test_upsert
USING btree
(name COLLATE pg_catalog."default", status, test_field, identifier);
但是,这将产生相同的结果,或者插入多个空行,或者在尝试插入时显示此错误消息:
错误:没有符合ON CONFLICT规范的唯一或排除约束
我已经尝试在部分索引上添加额外的详细信息,例如WHERE test_field is not null OR identifier is not null
。但是,在插入时我收到约束错误消息。
count = CASE WHEN EXCLUDED.count IS NULL THEN tu.count ELSE COALESCE(tu.count, 0) + COALESCE(EXCLUDED.count, 0) END
可被简化为count = COALESCE(tu.count+EXCLUDED.count, EXCLUDED.count, tu.count)