【问题标题】:Check Constraint with Filtering Logic使用过滤逻辑检查约束
【发布时间】:2020-06-04 02:04:01
【问题描述】:

我有一个表,它有一个名为“Flag”的位列,它不允许 NULL。这里的要求是始终为下表中的每个 Id 设置Flag=1,但每个唯一的 Id 和 Flag 列组合只有 1 次。同时,如果有超过 1 个条目,则所有其他行可以多次设置 Flag=0

基本上按 ID 分组的 Flag 的总和应始终为 1。

我虽然对 Id 和 Flag 字段有唯一约束,但由于 Flag=0 可以为同一组合设置多次,因此不能使用。

有什么建议吗?

-- 当前数据集

drop table if exists #test;
go
create table #Test (Id_pk int identity(1,1) not null, id int not null, Flag bit not null)
Insert into #Test (id, Flag) 
values (12, 0), (12,0), (12, 0), (12,0),  (12, 1), (12,1), (13,0), (13, 0), (14,1), (14,1), (20,1),  (20,0), (30,1),  (40,0)
select * from #Test

-- 期望的结果

drop table if exists #test;
go
create table #Test (Id_pk int identity(1,1) not null, id int not null, Flag bit not null)
Insert into #Test (id, Flag) 
values (12, 0), (12,0), (12, 0), (12,0),  (12, 0), (12,1), (13,0), (13, 1), (14,0), (14,1), (20,1),  (20,0), (30,1),  (40,1)
select * from #Test

【问题讨论】:

    标签: sql sql-server unique-constraint check-constraints


    【解决方案1】:

    您不是在寻找check 约束。你想要一个过滤的唯一约束:

    create unique index unq_test_id_flag
        on #test(id)
        where flag = 1;
    

    Here 是一个 dbfiddle。

    【讨论】:

    • 为了测试您的解决方案,我们应该无法在当前数据集表上创建这样一个唯一的约束/索引。事实并非如此......
    • @enigma6205 。 . .道歉。我只是完全输入了错误的语法。现在已修复。
    • 太棒了!谢谢你。我没有意识到我们可以使用覆盖索引来实现唯一性!
    • 我们仍然允许 ID 的 Flag=0。这是真正的挑战。
    • @enigma6205 。 . .是的,就像在 DB Fiddle 中一样。
    猜你喜欢
    • 2023-03-26
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2022-11-05
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多