Sql 列值的唯一约束
我有这张桌子:Sql 列值的唯一约束,sql,oracle,Sql,Oracle,我有这张桌子: ╔════╦══════╦══════╗ ║ ID ║ Test ║ DATA ║ ╠════╬══════╬══════╣ ║ 1 ║ Q ║ I ║ ║ 2 ║ Q ║ I ║ ║ 3 ║ Q ║ A ║ ║ 4 ║ Q ║ A ║ ║ 5 ║ Q ║ A ║ ║ 6 ║ X ║ A ║ ║ 7 ║ X ║ A ║ ║ 8 ║ Z ║ I ║ ║ 9 ║ Z
╔════╦══════╦══════╗
║ ID ║ Test ║ DATA ║
╠════╬══════╬══════╣
║ 1 ║ Q ║ I ║
║ 2 ║ Q ║ I ║
║ 3 ║ Q ║ A ║
║ 4 ║ Q ║ A ║
║ 5 ║ Q ║ A ║
║ 6 ║ X ║ A ║
║ 7 ║ X ║ A ║
║ 8 ║ Z ║ I ║
║ 9 ║ Z ║ I ║
╚════╩══════╩══════╝
我想对列值而不是列应用唯一约束。所以,如果数据包含I,那么就没有重复,如果它包含A,那么就可以了
结果集将是
╔══════╦═══╗
║ Test ║ D ║
╠══════╬═══╣
║ Q ║ I ║
║ Q ║ A ║
║ Q ║ A ║
║ Q ║ A ║
║ X ║ A ║
║ X ║ A ║
║ Z ║ I ║
╚══════╩═══╝
有可能吗?Oracle不支持筛选索引,但您可以使用表达式进行基本相同的思考:
create unique index idx_t_test_id
on t(test, (case when data = 'I' then 0 else id end));
这假定id是唯一的,并且从不为0。这样可以防止表中出现重复的I值
编辑:
我突然想到,您只需要一个查询结果。如果是:
select test, data
from (select t.*,
row_number(*) over (partition by test, data order by id) as cnt
from t
) t
where cnt = 1 or data <> 'I';