2012-01-20 32 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不知道要更新哪个记录......多数民众赞成我真正的问题。 ..任何想法? –