2012-06-27 4 views
0

У меня есть таблица со столбцом, где значения не должны быть одинаковыми. Из-за плохой реализации программное обеспечение не проверяет, входит ли пользователь в дубликат или нет, поэтому мне была поручена задача написать «простой» SQL-запрос или функцию, которая будет рассматривать все значения в столбце и гарантировать, что они не являются идентичны. Сам sql будет выполняться один раз в месяц, поэтому он не должен быть эффективным.Убедитесь, что значения не совпадают в столбце

В столбце хранится int, и я хотел бы увеличить одно из повторяющихся значений и продолжать делать это каждый раз, пока в таблице не будет больше записей, имеющих одинаковое значение для столбца. Любое предложение, что я должен делать? Я не знаю, с чего начать.

Спасибо всем за понимание.

EDIT: Извините, забыл упомянуть, что значения в данных, которые не дублируются, должны оставаться такими. Это настройки, используемые для клиентов, и мы должны наказать их, только если они имеют повторяющиеся значения. Если они этого не сделают, тогда мы не должны разрушать их настройки, или они будут злы.

Это всего лишь одна таблица, содержит много столбцов, но этот конкретный столбец, в частности, который имеет тип int и никогда не содержит никаких нулей, не должен иметь дубликатов.

+0

Для чего предназначена эта колонка? –

+0

@Quillion, сколько количество столбцов вы должны проверить, пожалуйста, также уточните структуру таблицы. –

+0

Этот столбец ссылается на любую другую таблицу или данные? Похоже, что он должен был первоначально быть столбцом auto_increment и теперь вы пытаетесь снова заставить значения снова быть уникальными. Но если это так, есть вероятность, что вы используете его в качестве внешнего ключа, где (хотя и без ограничения внешнего ключа). Кроме того, действительно ли имеет значение, какое новое значение вы даете любому из дубликатов? Разве это не просто неиспользуемое целое число? – MatBailie

ответ

1
create table tableName (KeyCol int identity(1,1), intCol int) 
insert into tableName values (1), (2), (2), (3), (5), (6), (5), (7), (9) 


While exists (
    select intCol 
    from tableName 
    group by intCol 
    having count(*) > 1 
) 
begin 

    declare @newValue int 

    select @newValue = min(t1.intCol) + 1 
    from tableName t1 
    left join tableName t2 
    on t1.intCol + 1 = t2.intCol 
    where t2.intCol is null 

    update tx 
    set intCol = @newValue 
    from tableName tx 
    where intCol = 
    (select top 1 intCol 
    from tableName t1 
    group by intCol 
    having count(*) > 1 
    order by intCol) 
    and KeyCol = (select min(KeyCol) from tableName t2 where t2.intCol = tx.intCol) 
end 

select * from tableName order by 2 
+0

Хорошо, мой код был полон ошибок! Вот рабочая версия для SQL2008: http://sqlfiddle.com/#!3/19801/2 – Sean

+0

Большое спасибо! Я попробовал, и это работает, это отличное решение! – Quillion

0

Почему бы не отбросить эту колонку и не воссоздать или повторно заполнить ее уникальными данными и надеть ее УНИКАЛЬНЫЙ ИНДЕКС?

+0

Если допустимо пересчитать любое из этих значений, я бы предположил, что допустимо перечислить их все. В этом случае это может быть хорошим вариантом быстрого выигрыша. За исключением того, что ОП подразумевает, что причина проблемы не будет исправлена, и поэтому это будет повторяться каждый месяц, все медленнее и медленнее. Arg! *** [OP только что опубликовал редактирование, чтобы сказать, что это не вариант ...] *** – MatBailie

+0

Если эти значения не очень важны (поскольку они могут быть изменены), он может использоваться в качестве столбца автоматического обрезания. – ALZ

1

Чтобы понять размер проблемы, попробуйте что-то вроде следующего: это синтаксис Oracle, поскольку я не знаю mysql, но должен быть эквивалент.

SELECT your_col, COUNT(your_col) 
    FROM your_table 
GROUP BY your_col 

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

Извините, если это не то, что вы надеялись :-)

ETA Ваша компания является неправильным, работает под управлением SQL один раз в неделю не будет дешевле, по крайней мере в долгосрочной перспективе. Вы шлепаете штукатурку на что-то, что требует швов. Намного лучше взять удар сейчас и решить основную проблему, для начала, столбец, который не хочет дубликатов, но позволяет им входить в любом случае? Для начала стоит WTF.

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