2017-08-30 29 views
2

我有如下表:是否可以在排除约束中使用IS NOT DISTINCT FROM?

CREATE TABLE claim (
    claim_number TEXT NOT NULL, 
    line_id TEXT, 
    process TEXT NOT NULL 
); 

我想添加一个约束它,因此claim_number和line_id的组合始终是唯一的。

在大多数情况下,line_id为null,并且该索赔编号只有一行。在某些情况下,给定的claim_number会有多行,在这种情况下,line_id将始终包含一个值。这里的目标是能够在(claim_number,line_id)组合中强制使用唯一组合的约束,以便我可以将它用作INSERT...ON CONFLICT DO UPDATE语句中的冲突目标,以便可以更新处理列。 UNIQUE约束不起作用,因为它不计算NULL = NULL,这是有道理的,但不是我所需要的。

我曾尝试加入排他条件如:

ALTER TABLE claim 
ADD EXCLUDE (claim_number WITH =, 
       line_id WITH IS NOT DISTINCT FROM); 

但是失败:

ERROR: syntax error at or near "IS" 

有在排除限制使用IS NOT DISTINCT FROM的方法吗?

+3

Whyis line_id可为空?为什么是文字? (它似乎是一个数字) – wildplasser

+1

一个简单的解决方法是定义一个默认值,它将等于您在应用程序中当然会处理的NULL值。也想知道为什么这些列是TEXT ... –

+0

@wildplasser我把所有的ID作为TEXT,总是,所以具有前导零的值不会最终改变。例如,像009543219这样的SSN不应该作为INTEGER存储,因为它将丢失前导零。另外,claim_number中的数据是字母数字。基本上,如果我没有用它做数学,那么它不应该是一个数字。 –

回答

0

在MSSQL Server中,这是通过使用过滤唯一索引来完成的,其中过滤谓词是仅索引具有非NULL值的行。

我不是一个PostgreSQL的专家,但谷歌搜索显示它可能使用 “部分索引”:https://www.postgresql.org/docs/current/static/indexes-partial.html

CREATE UNIQUE INDEX ix_claim_lines ON claim (claim_number, line_id) 
    WHERE line_id IS NOT NULL 
+0

我不确定这是否适用于此实例,因为我需要索引来覆盖整个表,而不仅仅是它的一部分,以便它可以根据需要使用“ON CONFLICT DO UPDATE”语句。 –

+0

@GregoryArenius此索引覆盖整个表格。此索引不用于搜索或查询性能,只有在指定了'line_id'时才强制'claim_number' +'line_id'的'UNIQUE'约束。也许有比使用'ON CONFLICT'更好的方法? – Dai

+0

@GregoryArenius:部分索引会阻止('claim_1','line_1')被第二次插入。但缺点是部分索引(如排除约束)不能用于'on conflict'子句。而且您无法使用部分索引创建唯一的_constraint_。底线是:你可以阻止这些行被插入,但是你不能在冲突时使用这个限制 –

相关问题