在create table语句中相互排斥的行

时间:2011-04-30 12:28:34

标签: sql database rows

我必须创建一个表,其中包含一个人的名字和姓氏,或一个组织的名称。必须有其中一个。例如,表格的一行是 -

first_name  last_name  organization
----------  ---------  ------------
John        Smith      null

或另一行可以是 -

first_name  last_name  organization
----------  ---------  --------------------
null        null       HappyStrawberry inc.

有没有办法用SQL语言定义它?或者我应该只定义所有三列能够获得空值?

3 个答案:

答案 0 :(得分:2)

你的情况是一些ER方言称之为“实体子类型”的经典例子。

您有一个名为“Person”(或“Party”或类似的东西)的实体,并且您有两个分别称为“NaturalPerson”和“LegalPerson”的独立子实体。

在关系数据库中建模ER实体子类型的规范方法是使用三个表:一个用于“Person”实体,其中所有列对于NaturalPerson和LegalPerson都是“通用”(即人员存在,无论他们是谁类型),以及每个已识别的子实体,其中包含特别属于该子实体的所有列。

您可以在Fabian Pascal的“数据库管理中的实际问题”中阅读更多相关内容。

答案 1 :(得分:0)

您可以使用检查约束,例如:

create table YourTable (
    col1 varchar(50)
,   col2 varchar(50)
,   col3 varchar(50)
,   constraint TheConstraint check ( 1 =
        case when col1 is null then 1 else 0 end +
        case when col2 is null then 1 else 0 end +
        case when col3 is null then 1 else 0 end )
)

另一种方法是添加type列(EAV方法):

create table YourTable (
    type varchar(10) check (type in ('FirstName', 'LastName', 'Organisztion')
,   value varchar(50))
insert YourTable ('LastName', 'Obama')
insert YourTable ('FirstName', 'Barrack')
insert YourTable ('Orginazation', 'White House')

答案 2 :(得分:0)

您可以使用约束

执行此操作
CREATE TABLE [dbo].[Contact](
    [first_name] [varchar](50) NULL,
    [last_name] [varchar](50) NULL,
    [organization] [varchar](50) NULL,
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Contact]  WITH CHECK ADD  CONSTRAINT [CK_Contact] CHECK  (([first_name] IS NOT NULL OR [last_name] IS NOT NULL OR [organization] IS NOT NULL))
GO

ALTER TABLE [dbo].[Contact] CHECK CONSTRAINT [CK_Contact]
GO

CK_Contact约束确保至少输入了一个值。