2016-06-07 41 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

相關問題