仔细查找重复项

时间:2013-05-06 21:05:27

标签: sql-server tsql duplicates

我有一个名为MyTable的表,其中包含字段Id(int),Name(nvarchar),Value1(bit),Value2(bit) EX:

1   Nathan  True    False
2   Nathan  True    False
3   John    True    False
4   John    False   True

所以我可以很容易地找到这样的副本:

select 'First_Id'=a.Id,'First_Value1'=a.Value1,'First_Value2'=a.Value2, 
        'Second_Id'=b.Id,'Second_Value1'=b.Value1,'Second_Value2'=b.Value2
        from MyTable a, MyTable b where a.Id>b.Id
        and a.Name = b.Name

然后我可以删除带有SecondId中的Id的那些......

我想要做的是找到重复项并在重复组的所有Value1之间执行逻辑OR,并使用该值更新重复项中的每个记录,然后为value2更新相同的内容。

EX:

对于上面的示例,将有2组重复

,结果将是:

1 Nathan True False
2 Nathan True False
3 John   True True
4 John   True True

我该怎么做?

2 个答案:

答案 0 :(得分:1)

试试这个:

update a set a.Value1=b.new_value1  ,a.Value2=b.new_value2

from MyTable a
inner join 
(select Name,cast(SUM(cast(Value1 as int))as bit) new_value1,
cast(SUM(cast(Value2 as int)) as bit) new_value2 from MyTable
group by Name) b

on a.Name=b.Name;

select * from MyTable

SQL Fiddle

说明:{/ strong> cast(Value1 as int)是必需的,因为SUM无效bit。然后cast(SUM(cast(Value1 as int))as bit)将任何非零值转换为1(真)。

Reference

答案 1 :(得分:0)

我对你的问题做了一些假设并产生了SQLFiddle Here

我做的假设是你的最大组数只有两个,也就是说,每个名称最多只复制一次。如果这是正确的,这就是你可以做的。您在SQL Server中使用按位函数将“OR”值一起使用。因此,使用ORed值更新每个名称的每一行的查询可以是:

;with upd_val_cte as 
 (select a.Name, (a.Value1 | b.Value1) as Value1,
 (a.Value2 | b.Value2) as Value2
from MyTable a
join MyTable b
on a.Name=b.Name
and a.id<b.id)

update MyTable 
set Value1=d.Value1,
    Value2=d.Value2 
from upd_val_cte d
where MyTable.Name=d.Name

如您所示,为了查看带有“true”或“false”字样的结果,您可以使用以下select语句。

select id, Name, case when Value1=1 then 'true' else 'false' end as Value1,
                case when Value2=1 then 'true' else 'false' end as Value2
from MyTable

在SQL Server中,位列中的值0表示false,1表示为true,因此,您可能希望直接使用这些值。

如果你有多个具有相同名称值的元组,请告诉我......顺便问一下,你能告诉我们你为什么要这样做吗?

这是在SQL Server 2008中进行按位操作的参考。

MSDN article on Bitwise operations