2013-02-13 3 views
1

Я очень новичок в SQL, поэтому мне нужна помощь с проблемой.Удалить две аналогичные записи

Я использую программное обеспечение для мониторинга файлов, размещенных на некоторых компьютерах, когда файл записан, запись записывается в базу данных и снова, когда она удаляется. Я хотел бы удалить любые записи, содержащие обе записи. Таблица аналогична приведенной ниже.

Столбец действие показывает 0, когда создается файл и 1 при удалении

datetime  File hash value      action 
130213 14:33 | FDFGDFGDFGDFDFGVBVNVBNVBNVBNVNVBNVB | 0 
130213 14:34 | FDFGDFGDFGDFDFGVBVNVBNVBNVBNVNVBNVB | 1 

Любая помощь будет оценена. S

ответ

1

Вы можете использовать объединение, чтобы потребовать, что есть запись с другим действием:

delete t1 
from Table1 t1 
join Table1 t2 
on  t1.[File hash value] = t2.[File hash value] 
     and t1.Action <> t2.Action; 

Для просмотра строк, которые будут удалены, замените delete с select:

select t1.* 
from Table1 t1 
join Table1 t2 
on  t1.[File hash value] = t2.[File hash value] 
     and t1.Action <> t2.Action; 

Example at SQL Fiddle.

+0

Спасибо, какой был бы лучший способ увидеть результат сравнения до его замены для удаления? Просто хочу убедиться, что его получение правильной информации – Simon

+0

Кажется, отлично работает, спасибо за это. Могу ли я задать еще один вопрос, связанный с этим. В этой таблице также есть другое поле, называемое «компьютер». Это можно учитывать и с учетом этого? Моя проблема в том, что если два разных компьютера копируют один и тот же файл и один файл удаляется, запись для обоих будет потеряна. Как это можно достичь? – Simon

+0

Добавьте условие для 'и t1.Computer = t2.Computer' точно так же, как проверка для' [Хэш-значение файла] ' – Andomar

0
create table test (
    dt datetime, 
    hv varchar(255), 
    action int 
) 

insert into test values (getDate(), '123456', 0); 
insert into test values (getDate(), '123456', 1); 

delete a1 from test a1 
join test a2 on a1.hv = a2.hv 
where a1.action <> a2.action 
+0

ugh, я получил бит :( – epoch

0

Вы можете выбрать файлы для удаления в подвыборки

delete from files 
where file_hashes in (select file_hashes 
         from files 
         group by file_hashes 
         having count(file_hashes) = 2) 

SQLFiddle

Чтобы увидеть, какие строки будут удалены, вы можете использовать подзапрос

select file_hashes 
from files 
group by file_hashes 
having count(file_hashes) = 2 
0

Если вы используете SQL Server 2005 или более поздней версии, вы можете попробовать следующее:

WITH marked AS (
    SELECT 
    CanDelete = 
     CASE MIN(Action) OVER (PARTITION BY FileHashValue) 
     WHEN MAX(Action) OVER (PARTITION BY FileHashValue) 
     THEN 0 
     ELSE 1 
     END 
    FROM atable 
) 
DELETE FROM marked 
WHERE CanDelete = 1 
; 

marked CTE проверяет каждую строку, соответствует ли соответствующее минимальное действие FileHashValue таким же, как максимальное. Если это не так, строка помечена для удаления.

Исходя из этого атрибута, строки удаляются в основном запросе, где CTE используется в качестве цели оператора DELETE.

Запрос предполагает, что Action является int и может быть только либо 0 или 1. Если это bit, замените как Action записей с помощью CAST(Action AS int).

Смежные вопросы