2012-01-20 35 views
2

問候所有...合併幾乎重複的記錄在SQL

我有兩個表,其結構是相同的......

表設置logdetail

Date    Time   CardID  Status 
2012-01-20  00:00:00  A1   ABSENT 
2012-01-20  00:00:00  B1   ABSENT 
2012-01-20  00:00:00  C3   ABSENT 
2012-01-20  00:00:00  D1   ABSENT 

表preStatus

Date   Time  CardID  Status 
2012-01-20  07:00:10  A1   COMING 
2012-01-20  07:10:00  C3   COMING 
2012-01-20  08:00:00  B1   LATE 
2012-01-20  17:00:00  B1   BACK 
2012-01-20  17:10:10  A1   BACK 
2012-01-20  17:13:00  C3   BACK 

合併後

Date 
2012-01-20  07:00:10  A1   COMING 
2012-01-20  07:10:00  C3   COMING 
2012-01-20  08:00:00  B1   LATE 
2012-01-20  00:00:00  D1   ABSENT 
2012-01-20  17:00:00  B1   BACK 
2012-01-20  17:10:10  A1   BACK 
2012-01-20  17:13:00  C3   BACK 

請問有什麼可以,因爲在表合併這兩個表B有重複的記錄,當我做 合併...

merge into logDetail as Target 
using preStatus as Source 
on Target.L_Date=Source.L_Date 
and Target.L_Time='00:00:00' 
and Target.L_CardID=Source.L_CardID 
when matched then 

update set Target.L_Status=Source.L_Status, 
Target.L_Time=Source.L_Time 
when not matched then 
insert (L_Date,L_Time,L_CardID,L_Status) 
          values(Source.L_Date,Source.L_Time,Source.L_CardID,Source.L_Status); 

它說MERGE語句試圖更新或刪除同一行更比一次

任何幫助,非常感謝。

+0

的'C#'標籤似乎並沒有與此有關。 –

回答

1

您似乎不想合併這些表,因爲CardID不是主鍵。

即使有新的條目,其中stats =「BACK」,您仍然希望保留Status =「COMING」的條目。

我建議你分兩步做,首先插入preStatus數據,然後刪除存在「COMING」和「BACK」行的「ABSENT」行。

/* Insert new data */ 
insert logDetail 
select * from preStatus 

/* Delete Absent rows where there is a COMING or BACK row for the same item on the same day */ 
Delete logDetail 
from logDetail ld1 
where 
    /* Absent rows only */ 
    ld1.time = '00:00:00' 
and ld1.Status = 'ABSENT' 
/* And there must be a COMING or BACK row for the same card on the same day */ 
and exists (
    select 1 from logDetail ld2 
    where ld2.Date = ld1.Date 
    and ld2.CardID = ld1.CardID 
    and ld2.Time > '00:00:00' 
    and ld2.Status <> 'ABSENT' 
) 

爲同一日期,CardId中,而同樣的狀態刪除行,但那裏是一個後來時間:

Delete logDetail 
from logDetail ld1 
where 
ld1.status in ('COMING', 'BACK') 
/* COMING or BACK row only */ 
     /* for the same card on the same day, with a later time*/ 
and exists (
    select 1 from logDetail ld2 
    where ld2.Date = ld1.Date  
    and ld2.CardID = ld1.CardID 
    and ld2.Status = ld1.Status 
    and ld2.Time > ld1.Time 
) 
+0

這兩步應該可以作爲一個單獨的事務來完成,以糾正MERGE原子性的損失。 –

+0

第二步是冪等性的,即它可以在不改變結果的情況下重複,並且如果第一步失敗也不會起作用。 – Ben

+0

感謝本和所有人......它的作品像魅力!但我有另一個問...如果我想刪除幾乎重複的記錄,如何做到這一點...例如我有兩個記錄,但只有在列時間不同......我想只保留最古老記錄並刪除其他人......它是怎樣的人? –

0

匹配時不要做任何事情,這應該解決它?

+0

即時通訊這個句子有問題「MERGE語句試圖更新或刪除同一行不止一次」它引用表preStatus,因爲它看起來SQL不知道要更新哪個記錄......多數民衆贊成我真正的問題。 ..任何想法? –