У меня есть таблица базы данных MySQL с двумя столбцами, которые меня интересуют. Индивидуально они могут иметь дубликаты, но у них никогда не должно быть дубликатов ОБОИХ из них, имеющих одинаковое значение.
stone_id
может иметь дубликаты, если для каждого заголовка upsharge
другое значение, и наоборот. Но скажем, например, stone_id
= 412 и upcharge_title
= "sapphire", что комбинация должна выполняться только один раз.
Это нормально:
stone_id = 412 upcharge_title = "sapphire"
stone_id = 412 upcharge_title = "ruby"
Это НЕ нормально:
stone_id = 412 upcharge_title = "sapphire"
stone_id = 412 upcharge_title = "sapphire"
Есть ли запрос, который найдет дубликаты в обоих полях? И если возможно, есть ли способ установить, что моя база данных не позволяет этого?
Я использую MySQL версии 4.1.22
Вы должны настроить составной ключ между двумя полями. Для каждой строки потребуется уникальное значение stone_id и upcharge_title.
Что касается поиска существующих дубликатов, попробуйте это:
select stone_id,
upcharge_title,
count(*)
from your_table
group by stone_id,
upcharge_title
having count(*) > 1
Мне было полезно добавить индекс unqiue, используя "ALTER IGNORE", который удаляет дубликаты и применяет уникальные записи, которые звучат так, как вы хотели бы сделать. Таким образом, синтаксис будет выглядеть следующим образом:
ALTER IGNORE TABLE `table` ADD UNIQUE INDEX(`id`, `another_id`, `one_more_id`);
Это эффективно добавляет уникальное ограничение, означающее, что у вас никогда не будет дубликатов записей, а IGNORE удаляет существующие дубликаты.
Подробнее о eh ALTER IGNORE вы можете узнать здесь: http://mediakey.dk/~cc/mysql-remove-duplicate-entries/
Обновление: мне было сообщено @Inquisitive, что это может быть неудачно в версиях MySql > 5.5:
Не удается выполнить команду MySQL > 5.5 и в таблице InnoDB, а в Percona из-за их функция быстрого индексирования InnoDB [http://bugs.mysql.com/bug.php?id=40344]. В этом случае сначала запустите
set session old_alter_table=1
, а затем указанную выше команду будет отлично работать
Чтобы найти дубликаты:
select stone_id, upcharge_title from tablename group by stone_id, upcharge_title having count(*)>1
Чтобы ограничить это в будущем, создайте составной уникальный ключ в этих двух областях.
Вы можете найти дубликаты, подобные этому.
Select
stone_id, upcharge_title, count(*)
from
particulartable
group by
stone_id, upcharge_title
having
count(*) > 1
Кстати, сложное уникальное ограничение в таблице помешало бы этому в первую очередь.
ALTER TABLE table
ADD UNIQUE(stone_id, charge_title)
(Это действительный T-SQL. Не уверен в MySQL.)
эта служба SO помогла мне, но я тоже хотел знать, как удалить и сохранить одну из строк... здесь PHP-решение для удаления повторяющихся строк и сохранения одного (в моем случае было всего 2 столбца, и это находится в функции для очистки дублирующих ассоциаций категорий)
$dupes = $db->query('select *, count(*) as NUM_DUPES from PRODUCT_CATEGORY_PRODUCT group by fkPRODUCT_CATEGORY_ID, fkPRODUCT_ID having count(*) > 1');
if (!is_array($dupes))
return true;
foreach ($dupes as $dupe) {
$db->query('delete from PRODUCT_CATEGORY_PRODUCT where fkPRODUCT_ID = ' . $dupe['fkPRODUCT_ID'] . ' and fkPRODUCT_CATEGORY_ID = ' . $dupe['fkPRODUCT_CATEGORY_ID'] . ' limit ' . ($dupe['NUM_DUPES'] - 1);
}
(ограничение NUM_DUPES - 1) является тем, что сохраняет одну строку...
спасибо всем
ALTER IGNORE TABLE table ADD UNIQUE INDEX index_name(stone_id, charge_title)
удалит дублирующиеся строки, оставив только одну уникальную пару.