首页 > 解决方案 > 当 Postgres 中的列可以为空时处理索引上的冲突

问题描述

假设我有一张像这样的桌子:

CREATE TABLE test (id SERIAL, first VARCHAR(10), second VARCHAR(10), other VARCHAR(10));
CREATE UNIQUE INDEX unique_index ON test (first, second);

INSERT INTO test (first, second, other)
  VALUES ('lorem', null, 'old');

如果我填充此列并使索引中的第二个字段为空,但是在 null=null 的冲突中要更新什么,我该怎么做?目前,当 upsert 值也为空时,我没有遇到冲突。

INSERT INTO test (first, second, other)
  VALUES ('lorem', null, 'new')
ON CONFLICT (first, second)
  DO UPDATE SET
    other = EXCLUDED.other;

我会得到这样的输出:

1   lorem   (null)  old
2   lorem   (null)  new

如果我将第二列设置为任何值,这将有效,但是当它们为空时没有冲突。为什么?我该如何解决这个问题?

标签: sqlpostgresqlupsert

解决方案


您可以在表达式上创建索引。通常有效的是:

CREATE UNIQUE INDEX unique_index ON test (COALESCE(first, ''), COALESCE(second, ''));

当然,这假定这''不是有效的字段值。你总是可以把别的东西放进去。. . 比如'<null>'


推荐阅读