SQL:如何强制只在一组列中设置单个列

And*_*ite 10 sql constraints

在SQL中,是否有一种方法可以强制只有一组列中的一列具有值,而其他列为空?可能是约束还是触发?这种类型的东西可能用于查找表,但有没有任何替代表设计可以更好地实现这一点?

例如:

ID    OtherTable1ID    OtherTable2ID    OtherTable3ID
-----------------------------------------------------
1     23               NULL             NULL
2     NULL             45               NULL
3     33               55               NULL   -- NOT ALLOWED
Run Code Online (Sandbox Code Playgroud)

主要问题是这些列都是其他表的FK,因此我无法将它们折叠为单个列.

我正在使用SQL Server,但任何答案都可以.

Ale*_*lli 14

@ tvanfosson建议的约束对于三列是可行的,但为了一般性我更喜欢

(cast(col1 is not null, int) +
 cast(col2 is not null, int) +
 cast(col3 is not null, int)) = 1
Run Code Online (Sandbox Code Playgroud)

因为它可以更好地推广到任意数量的列,其中"线性增长"(而非"二次增长")编码量(在SQL方言中甚至更简洁,不需要将布尔式名称显式转换为int,但我是不确定SQL Server是否是其中之一).

  • 对于SQL Server,这可能会更好...(例如当col1 IS非NULL然后1 else 0 end + case col2 IS NOT NULL然后1 else 0 end <2) (4认同)
  • @Glen Little:同意所提供的语法,但我认为OP案例的比较应该仍然是“... = 1”。 (2认同)

tva*_*son 6

以下约束应该起作用:

 (column1 is null and column2 is null)
   or (column1 is null and column3 is null)
   or (column2 is null and column3 is null)
Run Code Online (Sandbox Code Playgroud)

但是,这不会强制它包含非空列.为此,添加另一个约束:

 column1 is not null
    or column2 is not null
    or column3 is not null
Run Code Online (Sandbox Code Playgroud)