使用值之间的Sql server关系

使用值之间的Sql server关系,sql,sql-server,sql-server-2008,foreign-keys,Sql,Sql Server,Sql Server 2008,Foreign Keys,我有一个包含2个表的数据库(SQLServer2008): 借贷者交易 ID int 佣金小数 佣金层 ID int 佣金小数 最大佣金小数 我想在这两个表之间创建一个关系。显而易见的方法是将CommissionTierId添加到LenderCommission表中,不过这是固定的。如果某一层级的佣金结构发生变化,则所有贷款佣金都需要重新估值 我不是专家,但我猜不可能在MinCommission和MaxCommission之间建立Commission关系。然而,有什么方法可以让这种关系变得更加流

我有一个包含2个表的数据库(
SQLServer2008
):

借贷者交易

ID int

佣金小数

佣金层

ID int

佣金小数

最大佣金小数

我想在这两个表之间创建一个关系。显而易见的方法是将CommissionTierId添加到LenderCommission表中,不过这是固定的。如果某一层级的佣金结构发生变化,则所有贷款佣金都需要重新估值


我不是专家,但我猜不可能在
MinCommission
MaxCommission
之间建立
Commission
关系。然而,有什么方法可以让这种关系变得更加流畅吗?

我不完全理解你的目标。表之间似乎已经存在逻辑关系;据推测,佣金可能介于最小值和最大值之间。您可以按以下方式进行连接:

select <whatever>
from LenderCommission lc join
     CommissionTier ct
     on lc.commission between ct.MinCommission and ct.MaxCommission;
选择
来自LenderCommission信用证加入
委托人ct
关于ct.MinCommission和ct.MaxCommission之间的lc.commission;
你想干什么

一种可能性是,您希望通过将此联接转换为相等联接而不是“中间”联接来提高其效率。拥有身份证肯定能做到这一点。如果CommissionTier表只有几十行,那么这种效率水平可能并不重要

也许您正试图在表之间强制执行约束,因此只能使用佣金层添加新佣金。如果是这样,您可以通过触发器进行检查

将此关系转换为单个外键将非常复杂。您需要考虑以下事项:

  • 防止佣金层级重叠
  • 当佣金级别更改时更改外键关系(即,修改
    eaderCommission
    中的数据)
  • 如果您需要在不同的时间点查看“它是什么”,请维护佣金层级上的历史数据

这些都是可能的,但可能比您想要的复杂得多。

我不确定您想做什么-我已经准备了一个演示,演示了一种您可能希望事情正常运行的方法。我们实际上创建了一个包含更多列的表,然后用几个触发器将其隐藏在视图后面,以确保所有内容都正常运行效果很好

各表:

create table dbo.CommissionTier (
    ID int not null,
    MinCommission decimal not null,
    MaxCommission decimal not null,
    constraint PK_CommissionTier PRIMARY KEY (ID),
    constraint UQ_CommissionTier_RangeValidation UNIQUE (ID,MinCommission,MaxCommission) --This is to support our FK below
)
go
create table dbo._LenderCommission (
    ID int not null,
    Commission decimal not null,
    CommissionTier int not null,
    _MinCommission decimal not null,
    _MaxCommission decimal not null,
    constraint PK__LenderCommission PRIMARY KEY (ID),
    constraint CK__LenderCommission_InRange CHECK (
        _MinCommission < Commission and --Inclusive or exclusive bound? <= or <
        Commission < _MaxCommission --Ditto?
    ),
    constraint FK__LenderCommission_Tier
       FOREIGN KEY (CommissionTier)
       references dbo.CommissionTier (ID), --This FK isn't actually needed
    constraint FK__LenderCommission_Tier_Range
       FOREIGN KEY (CommissionTier,_MinCommission,_MaxCommission)
       references dbo.CommissionTier(ID,MinCommission,MaxCommission) on update cascade
)
您可能不需要这样做,但我倾向于在视图伪装为表时始终添加索引,并将其命名为与原始主键相同的名称:

create unique clustered index PK_LenderCommission on dbo.LenderCommission(ID)
现在有几个触发器可以进行必要的房屋清洁:

create trigger dbo.T_LenderCommission_I
on dbo.LenderCommission
instead of insert
as
    set nocount on

    insert into dbo._LenderCommission (ID,Commission,CommissionTier,_MinCommission,_MaxCommission)
    select i.ID,i.Commission,i.CommissionTier,ct.MinCommission,ct.MaxCommission
    from
        inserted i
            inner join
        dbo.CommissionTier ct
            on
                i.CommissionTier = ct.ID
go
create trigger dbo.T_LenderCommission_U
on dbo.LenderCommission
instead of update
as
    set nocount on

    update lc
    set
        Commission = i.Commission,
        CommissionTier = i.CommissionTier,
        _MinCommission = ct.MinCommission,
        _MaxCommission = ct.MaxCommission
    from
        dbo._LenderCommission lc
            inner join
        inserted i
            on
                lc.ID = i.ID
            inner join
        dbo.CommissionTier ct
            on
                i.CommissionTier = ct.ID
现在我们填充它们:

insert into CommissionTier(ID,MinCommission,MaxCommission) values
(1,0,1000),
(2,1000,2000),
(3,2000,3000)
go
insert into LenderCommission(ID,Commission,CommissionTier) values
(1,500,1),
(2,750,1),
(3,1500,2)
现在来看一些错误:

--This produces an error:
insert into LenderCommission(ID,Commission,CommissionTier) values
(4,500,2)
go
--This produces an error:
update LenderCommission set Commission = 2500 where ID=2
go
--This *doesn't* produce an error because the new value matches the new tier
update LenderCommission set Commission = 2500,CommissionTier = 3 where ID=2
go
--This is okay, we're adjusting one of the tiers
update CommissionTier set MaxCommission = 1550 where ID = 2
go
--This produces an error, because the cascading foreign key updated the values:
update LenderCommission set Commission = 1600 where ID = 3

作为上述方法的替代方法,您可以创建一个计算列,执行相同的检查并采用适当的值,而不是在范围内使用
CK\uu LenderCommission\u

CommissionOutOfRange AS
  CASE WHEN Commission < MinCommission THEN -1
  CASE WHEN Commission > MaxCommission THEN 1
  ELSE 0 END
CommissionAutofrange AS
佣金最大佣金然后为1时的情况
其他0结束

现在,您可以快速搜索表中超出范围的值(但没有什么能阻止它们的创建

我不清楚您想要实现什么-您已经开始建议您可能采取的各种方法,但没有真正说明您想要什么。您是否希望数据库强制执行
佣金
符合所需级别?以及当
佣金级别
更新了吗?
CommissionOutOfRange AS
  CASE WHEN Commission < MinCommission THEN -1
  CASE WHEN Commission > MaxCommission THEN 1
  ELSE 0 END