2016-06-07 37 views
2

这一个正在窃听我。SQL Server:只更新多个完全重复的记录中的一个

我在一个数据仓库临时表中工作,其中可能有列值为其他列的100%重复的行。有几十个栏目,但对于这种说法的缘故,让我们用下面的例子:

tblExample (ID Int, Active bit, ModifiedDate DateTime) 

现在,在任何给定的时间也就只应该是每有活动设置为1 ID一个记录。所有其他应该有活动设置为0.有一个过程,在数据加载过程中强制执行此操作。

这个过程会和过去已破裂,从而导致数据是这样的:

ID  Active ModifiedDate 
123456 0  2016-05-27 12:37:46.111 
123456 1  2016-05-27 12:37:46.433 
123456 1  2016-05-27 12:37:46.433 

在这种情况下,有2个“相同”的记载有主动设置为1 我需要找到一个方法来使这些记录只有一个有效= 1。

现在我正在使用的过程中,目前假定日期值是唯一的,在99.99%的时间是这种情况。但有些时候日期也会重复。而且我不能为了我的生活找出一种方法来只更新那些记录中的单个记录,因为我没有任何东西可以锁定到WHERE。

  • 我无法添加或修改架构。
  • 这一切发生内部,所以我仅限于固有的与平台(有些东西只是不SSIS中很好地工作)

观念的限制?

+1

这就是为什么主键是重要的。 – Tyler

+1

那么我能看到的第一个解决方法是将它全部更新为零,然后更新只有最大日期限制为1的那个。 –

+0

只是想着,我从专业人士(因此写作评论)faaaar,但你可以创建一个CTE'选择顶部1 ...',然后更新CTE? –

回答

3

这应该工作:

with a as(
select *, ROW_NUMBER() OVER (PARTITION by ID, Active, ModifiedDate order by ModifiedDate) as rn from tblExample 
)  

update a set active = 0 where rn >1 
select * from tblExample; 

Here is an example与您的数据。

ModifiedDate(因为您的解决方案适用于非欺骗ModifiedDate)创建CTE Row_number()并更新CTE,更新您的数据。

如果您要更换你的过程中,你可以使用如下:

with a as(
select *, ROW_NUMBER() OVER (PARTITION by ID, Active order by ModifiedDate desc) as rn from tblExample 
) 

update a set active = 0 where rn >1 
select *, ROW_NUMBER() OVER (PARTITION by ID, A order by ModifiedDate desc) as rn from tblExample; 

这仅允许每个ID是积极最新的条目

Alternative solution

+0

很好的回答! –

+0

CTE会在SSIS中工作吗?我承认我没有尝试过,但如果确实如此,我会感到非常惊讶。正如我所说的,SSIS非常有限。我会尽力去看看。 –

+0

@DavidBorneman它应该!您可能需要添加';'设置之前的分号:';用as ...'如果出于某种原因,CTE不起作用(不同的连接等),你可以用RowNumber()创建一个临时表并将值加载回表中 – EoinS

相关问题