在其他列中排除具有相同值的行的唯一约束(Unique constraint on one column with excluding row with same values in other)

我想为列value添加一个唯一键,但我必须忽略在列value和header_id中具有相同值的行。 例如,请考虑下表:

id | header_id | value 1 | 1 | a 2 | 1 | a 3 | 2 | a

因此第1行和第2行指向相同的对象,唯一的键应该接受它们,但第3行有一个不同的header_id (指向另一个对象),并且因为它与对象1具有相同的value ,所以它应该违反唯一约束并引发错误。

编辑16.2:1327: 我正在使用生成列来处理历史记录的核心框架,所以我无法规范化表格。 我的类有很多列但是对于这个例子我只考虑value列。

I'd like to add a unique key to column value but I must ignore rows that have the same values in columns value and header_id. For example, consider this table:

id | header_id | value 1 | 1 | a 2 | 1 | a 3 | 2 | a

So rows 1 and 2 point to same object and the unique key should accept them, but row 3 has a different header_id (pointing to another object) and, because it has the same value as object 1, it should violate unique constraint and raise an error.

Edit 16.2:1327: I'm using a core framework that generates columns to handle history so I cannot normalize the table. My class has lots of columns but for this example I'm only considering the value column.

最满意答案

你可以做到这一点,如果你可以稍微改变你的表格结构:

your_table id header_value 1 1 2 1 3 2 header_value id header_id value 1 1 a 2 2 a

将your_table.header_value的外键约束添加到header_value.id 。

现在你可以在header_value.value上添加一个唯一的约束。

After a while I found something. Using constrain CHECK with function to determine if exist (Cannot use SELECT in CHECK statement but you can use function with desired select)

CREATE OR REPLACE FUNCTION is_value_free(_header_id integer, _value varchar) RETURNS BOOLEAN AS $$ BEGIN RETURN NOT EXISTS (SELECT header_id,value FROM myschema.mytalbe WHERE value LIKE _value AND header_id != _header_id LIMIT 1); END; $$ LANGUAGE plpgsql; ALTER TABLE mytable ADD CONSTRAINT uniq_value CHECK (is_value_free(header_id,value))

更多推荐