2013-05-06 4 views
0

У меня есть таблица с именем MyTable с полями Id (INT), Name (NVARCHAR), Значение1 (бит), Value2 (бит) 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 ...

Что я хочу сделать, это найти дубликаты и сделать логический ИЛИ между всеми Value1 дублирующей группы и обновить каждую отдельную запись из дубликатов с этим значением, а затем то же самое для value2.

EX:

Для приведенного выше примера будет 2 группы дублей

и результат будет:

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

Как я могу это сделать?

+0

Вы говорите, вы хотите обновить 'Value1' и' Value2' для каждой группы, так что они такие же, как в первом ряду в этой группе? – imthepitts

ответ

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

Объяснение:cast(Value1 as int) требуется, как SUM будет не работает bit. А затем cast(SUM(cast(Value1 as int))as bit) преобразует любое ненулевое значение в 1 (true).

Reference

+0

@Nathan: Помогает ли это? –

+0

Да ... это именно то, что мне нужно ... Я даже не понимаю, что делает это кастинг от int до бит ... каждое число, большее, чем 0, рассматривается как 1 (true) при нажатии ... почему? – Nathan

+0

Вы правы. Это можно удалить. –

0

Я сделал несколько предположений о вашем вопросе и произвел SQLFiddle Here

Предположение я сделал это, что вы будете иметь максимальное количество групп из двух, то есть, каждое имя только дублированы, в лучшем случае, один раз. Если это правильно, вот что вы можете сделать. Вы используете побитовые функции в SQL Server для значений «ИЛИ» вместе. Таким образом, запрос, чтобы обновить каждую строку для каждого имени со значениями 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 

Для того, чтобы увидеть результаты со словами «истина» или «ложь», как вы показали, вы можете использовать следующие выберите оператор.

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 в битовой колонке представляет собой ложь и 1 верно, таким образом, вы можете использовать их непосредственно.

Если у вас может быть более одного кортежа с одинаковым значением имени, дайте мне знать ... Кстати, вы могли бы рассказать нам, почему вы хотите это сделать?

Вот ссылка для выполнения Битовые операции в SQL Server 2008.

MSDN article on Bitwise operations

+0

ваш запрос выглядит хорошо, но он не даст правильного ответа, если я добавлю еще один Nathan 0 1 .. – Nathan