2015-05-22 2 views
4

Это кажется простым, но я ничего не смог найти. Любая помощь приветствуется.Запрос на удаление строк, где совпадение столбцов или NULL

У меня есть стол с несколькими колоннами. Мне нужно сравнить несколько этих столбцов друг с другом и удалить строки, в которых они соответствуют друг другу, или NULL. Иными словами, мне нужно оставить строки только там, где есть отличия, отличные от NULL. (Если это имеет значение, я буду запускать это несколько раз против таблиц с различным количеством сопоставляемых столбцов, иногда очень много столбцов, поэтому все запросы, в которых сосредоточены только три столбца, не будут работать.)

Итак, если мой стол:

ID TITLE VALUE_1 VALUE_2 VALUE_3 
1 One  AAA  NULL NULL 
2 Two  NULL AAA  AAA 
3 Three AAA  AAA  AAA 
4 Four NULL NULL NULL 
5 Five AAA  BBB  CCC 
6 Six  AAA  BBB  NULL 
7 Seven NULL DDD  EEE 
8 Eight AAA  AAA  BBB 

После выполнения запроса, я хочу иметь

ID TITLE VALUE_1 VALUE_2 VALUE_3 
5 Five AAA  BBB  CCC 
6 Six  AAA  BBB  NULL 
7 Seven NULL DDD  EEE 
8 Eight AAA  AAA  BBB 

Еще раз спасибо за ваше время.

+3

Это было бы намного проще, если ваши данные были нормализованы. –

ответ

3
select * from table 
where v1 <> v2 or v1 <> v3 or v2 <> v3 

Это будет возвращать строки, где будет TRUE для любой пары. Так, окружающий этот предикат с NOT IN придаст нужный набор для удаления:

delete t where id not in(select id from t where v1 <> v2 or v1 <> v3 or v2 <> v3) 

Вот скрипку http://sqlfiddle.com/#!3/ea7172/8

+0

Это замечательно! Это отлично работает. Спасибо, я думаю, это глупый вопрос, но можете ли вы объяснить, почему этот выбор не возвращает первые две строки? В обеих строках v1 <> v2 ('aaa' не является NULL), но они не возвращаются select и, следовательно, не удаляются. Опять же, чтобы быть ясным, это именно то, что я хочу, я просто пытаюсь понять, как это работает. – THEMEDIA

+0

Хорошо, выбор будет выбирать только строки, где предикат в where, где выражение оценивается как true. Если он оценивает значение false или неизвестно (неизвестно будет, если есть нуль, по крайней мере, на одной стороне), строка будет отфильтрована. строка 1. Aaa <> null или aaa <> null или null <> null => неизвестно или неизвестно или неизвестно => неизвестно, оно будет отфильтровано. Для строки 7. Null <> ddd или null <> eee или ddd < > eee => unknown или unknown или true => true. Так что строка 7 не будет отфильтрована, она будет в resultset –

+0

Я все еще немного смущен, но это намного яснее. Еще раз спасибо за запрос и объяснение. – THEMEDIA

0

Вы можете использовать ISNULL как это в вашем DELETE заявления

Where IsNull (Value_1, 'SomeValueThatWillNeverBeInTheTable') = IsNull (Value_2, 'SomeValueThatWillNeverBeInTheTable')

1
Delete from tablename 
     where (Value_1 is Null And value_2 is null) 
      or (Value_2 is Null And value_3 is null) 
      or (Value_1 is Null And value_3 is null) 
      or (Value_1 = value_2) 
      or (Value_1 = value_3) 
      or (Value_3 = value_2) 

Это должно быть в состоянии удалить, если есть два столбца нуля, или любой соответствующие два столбца. Существует не строка не сравнивать функции в SQL сервера в случае, если вы задаетесь

+0

Я не думаю, что это дает ему то, что он хочет. Нуль может присутствовать в одном или нескольких столбцах, он просто хочет удалить строку, если есть два столбца, которые НЕ являются нулевыми, которые имеют одинаковые данные. –

+0

Я думаю, что весь вопрос можно суммировать так: «Мне нужно оставить строки только там, где есть отличия, отличные от NULL», однако это конфликтует с тем, почему он удалил строку 1, поэтому я думаю, что он хочет удалить любую строку, где любой два столбца равны, NULL или нет ... –

+0

@TonyHinkle получил это! отредактировал мой ответ –

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