我正在尝试确定一种处理下面方案的好方法。我有以下两个数据库表,以及示例数据。表1包含按项目分组的分布。项目可以有一个或多个发行版。分发可以有一个或多个帐户。帐户分配了一个百分比。可以通过添加或删除帐户以及更改百分比来修改分发。
表2跟踪分布,为每个分布分配版本号。 我需要能够将新的分布从Table1复制到Table2,但只能在两个条件下:
1. the entire distribution does not already exist
2. the distribution has been modified (accounts added/removed or percentages changed).
注意:的 将分发从Table1复制到Table2时,我需要比较分发中的所有帐户和百分比,以确定它是否已存在。插入新分发时,我需要增加VersionID(max(VersionID)+ 1)。
因此,在提供的示例中,已修改分发(12345,1),添加帐号7,以及更改分配的百分比。应将整个分发复制到第二个表,在此过程中将VersionID增加到3。
有问题的数据库是SQL Server 2005。
Table1
------
ProjectID AccountDistributionID AccountID Percent
12345 1 1 25.0
12345 1 2 25.0
12345 1 7 50.0
56789 2 3 25.0
56789 2 4 25.0
56789 2 5 25.0
56789 2 6 25.0
Table2
------
ID VersionID Project ID AccountDistributionID AccountID Percent
1 1 12345 1 1 50.0
2 1 12345 1 2 50.0
3 2 56789 2 3 25.0
4 2 56789 2 4 25.0
5 2 56789 2 5 25.0
6 2 56789 2 6 25.0
答案 0 :(得分:0)
假设您知道从Table1中提取哪个分发版,您可以动态确定应该使用的版本,如下所示:
Insert Table2( VersionId, ProjectId, AccountDistributionId, AccountId, Percent )
Select Coalesce(
(
Select Max(VersionId)
From Table1 As T1
Where T1.Id = T.Id
), 0) + 1 As VersionId
, ProjectId, AccountDistributionId, AccountId, Percent
From Table1 As T
Where ProjectId = 12345
And AccountDistributionId = 1
关于确定更难的“任何新分布”,它取决于“新”的定义方式。
<强> ADDITION 强>
您询问了如何确定该设置已更改。一种解决方案是在保存时使用帐户分布存储值的哈希值。如下所示:
Update AccountDistributions
Set AccountHash = HashBytes('SHA1'
, (
Select '|' + Cast(AccountId As varchar(10)) + '|' + Cast(Percent As varchar(30))
From Table1 As T1
Where T1.AccountDistributionID = AccountDistributions.Id
Order By T1.AccountId, T1.Percent
For Xml Path('')
))
然后,您可以使用它来确定该组的任何成员是否已更改。另一种解决方案是每当对集合发生更改时将DateTime值更新到父表中,并将相同的值写入Table2。然后,您可以将最后一个DateTime与父表中的DateTime进行比较,以确定是否有任何更改。
答案 1 :(得分:0)
经过多次试验,我决定采用不同的方法。以下查询是所做内容的概要。
declare @accountDistributionVersionID int
select @accountDistributionVersionID = isnull(max(VersionID), 0)
from Table2
insert into Table2
select @accountDistributionVersionID + rank,
ProjectID, AccountDistributionID, AccountID, Percent
from
(
select D.*,
dense_rank() over (order by ProjectID, AccountDistributionID) as rank
from
(
select distinct t2.* from
(
select t.ProjectID, t.AccountDistributionID, t.AccountID, t.Percent
from Table1 as t
where not exists(select * from Table2 as t2
where t2.ProjectID = t.ProjectID
and t2.AccountDistributionID = t.AccountDistributionID
and t2.AccountID = t.AccountID
and t2.Percent = t.Percent
and VersionId = (select max(VersionID)
from compass.Table2 t3
where t2.ProjectID = t3.AccountDistributionID
and t2.AccountDistributionID = t3.AccountDistributionID) )
) as t
cross apply
(
select t3.ProjectID, t3.AccountDistributionID, t3.AccountID, t3.Percent
from Table1 As t3
where t.ProjectID = t3.ProjectID
and t.AccountDistributionID = t3.AccountDistributionID
) as t2
) as D
) as T
似乎运作良好。反馈将不胜感激。