2016-06-10 82 views
-1

我有一個數據集,其中包含基於特定字段的被視爲重複的行。我需要匹配重複的行,評估不匹配的字段,並將其中的一個標記爲刪除。的試樣臺是:根據匹配行的條件識別刪除/更新的行

ID Col1 Col2 Col3 
1 A  B  CC 
2 A  B  DD 
3 E  F  GG 
4 E  F  HH 

所以我需要確定行1 & 2基於col1和col2上匹配重複,並比較COL3字段,最終標記無論是行1或2爲刪除。第3行相同& 4.該表格完全由在Col1和Col2中至少與另一行匹配的行組成。

我首先想到的是加入到自己的行壓扁成這種格式:

t1.ID t2.ID t1.Col1 t1.Col2 TableOneCol3 TableTwoCol3 
1  2  A  B  CC    DD 
3  4  E  F  GG    HH 

那麼這將是簡單的評估TableOneCol3和TableTwoCol3每一行。 我試着用自己做這個加盟:

select t1.ID, t2.ID, t1.Col1, t1.Col2, t1.Col3 as TableOneCol3, t2.col3 as TableTwoCol3 
    into #temptable 
from tableOne t1 
    join tableTwo t2 
where t1.Col1 = t2.Col2 
and t1.Col2 = t2.Col2 
and t1.ID <> t2.ID 

當然,這並不排除重複可是 - 只是增加重複的場地信息,每一行。

我沿着擺動數據的路徑 - 但我最終得到了一個類似的結果 - 我樞軸重複以及。
我挖通過SO,但不知道我是否有我需要做的具體詞(公認的模糊標題可能是一個贈品 - 道歉)。我發現了很多將數據展平爲單列和樞軸的例子,但沒有任何東西會將成對的行平坦化並將其中一個從結果集中移除。

不知道我是否爲此而走錯路。看來我需要評估之前評估的內容中的每一行 - 但我不確定如何在不使用遊標的情況下執行此操作。

+0

「你最終如何標記第1行或第2行進行刪除」 - 沒有標準,你將無法以編程方式執行 – dbmitch

+0

有業務邏輯來評估哪一行被刪除,這與問題無關。這是我正在處理的數據的一個非常簡單的例子。 – pbrown

回答

0

你可以在類似於您使用LEAD()解析函數描述的一個形式獲取表。這將有一個好處,就是當你的骰子進入兩個以上的組時,它的效果會很好。例如:

select 
    ID, 
    lead(ID) over (partition by col1, col2 order by col3) as nextId, 
    Col1, 
    Col2, 
    Col3, 
    lead(Col3) over (partition by col1, col2 order by col3) as nextCol3 
into #temptable 
from tableOne 

結果會是這樣的形式

ID nextId Col1 Col2 Col3 nextCol3 
1  2  A  B CC  DD 
2 NULL  A  B DD  NULL 
3  4  E  F GG  HH 
4 NULL  E  F HH  NULL 

如果你有信心,你不需要處理大於二組,那麼你可以得到你想要通過精確的表之後過濾掉,例如,具有nextId IS NULL的行。

+0

鉛 - 真棒!是的,在這種情況下,我可以將表格嚴格限制爲兩個副本 - 刪除空值,然後評估剩餘部分以從主數據集中刪除行。謝謝! – pbrown

1

這是非常不清楚你在做什麼。我扔了幾個快速的想法,可能是你想要做的。

if OBJECT_ID('tempdb..#Something') is not null 
    drop table #Something 

create table #Something 
(
    ID int 
    , Col1 char(1) 
    , Col2 char(1) 
    , Col3 char(2) 
) 

insert #Something 
(
    ID 
    , Col1 
    , Col2 
    , Col3 
) 
VALUES 
(1, 'A', 'B', 'CC'), 
(2, 'A', 'B', 'DD'), 
(3, 'E', 'F', 'GG'), 
(4, 'E', 'F', 'HH'); 

with SortedResults as 
(
    select * 
     , ROW_NUMBER() over(partition by Col1, Col2 order by Col3) as RowNum 
    from #Something 
) 

delete SortedResults 
where RowNum > 1 

select * 
from #Something; 

--OR maybe you want to cross tab the data??? 

drop table #Something 

GO 

create table #Something 
(
    ID int 
    , Col1 char(1) 
    , Col2 char(1) 
    , Col3 char(2) 
) 

insert #Something 
(
    ID 
    , Col1 
    , Col2 
    , Col3 
) 
VALUES 
(1, 'A', 'B', 'CC'), 
(2, 'A', 'B', 'DD'), 
(3, 'E', 'F', 'GG'), 
(4, 'E', 'F', 'HH'); 

with SortedResults as 
(
    select * 
     , ROW_NUMBER() over(partition by Col1, Col2 order by Col3) as RowNum 
    from #Something 
) 

select 
    MAX(case when RowNum = 1 then ID end) as ID_1 
    , MAX(case when RowNum = 2 then ID end) as ID_2 
    , Col1 
    , Col2 
    , MAX(case when RowNum = 1 then Col3 end) as Col3_1 
    , MAX(case when RowNum = 2 then Col3 end) as Col3_2 
from SortedResults 
group by 
    Col1 
    , Col2 
+0

我的選擇是爲選項1. http://rextester.com/FWCU91123 –