MySQL. Надо уникализировать одно поле.

zhitov
На сайте с 30.01.2005
Offline
219
1109

По конец недели что-то голова совсем не варит :)

Есть таблица.

Есть одно поле, записи вида

5881с2f5b6f397c5a2bfa52ad36c7cf7
9d0aaa521с75e97fb6c01cffe015cd11
0fbbd14с91d5032e57cb38013a08c793
0fbbd14с91d5032e57cb38013a08c793
6d32537c6c490886f346706782c638b0

но часть записей неуникальна.

Задача уникализировать эти записи, затронув наименьшее кол-во строк.

Т.е. исправить только неуникальные записи. (Желательно с выводом id исправленных строк)

Как исправлять - неважно, хоть id припишу.

Нагородить скрипт с циклами можно, но может кто подскажет более элегантное решение?

Каким-нибудь "волшебным" запросом к таблице.

Строительные калькуляторы ( https://www.zhitov.com/ )
I
На сайте с 23.12.2010
Offline
25
#1
UPDATE list SET id = id + ROUND(100*RAND())
WHERE id IN (
SELECT id FROM list
GROUP BY id HAVING count(id) > 1)

добавит два случайных числа к id

edogs software
На сайте с 15.12.2005
Offline
775
#2
iopiop:
добавит два случайных числа к id

Во первых, не добавит, потому что апдейт таблицы на которую в этом же запросе делаешь селект - недопустим.

Во вторых, операцией сложения Вы прибили вообще информацию в хэшах.

zhitov:
По конец недели что-то голова совсем не варит :)

Есть таблица.
Есть одно поле, записи вида

но часть записей неуникальна.
Задача уникализировать эти записи, затронув наименьшее кол-во строк.
Т.е. исправить только неуникальные записи. (Желательно с выводом id исправленных строк)
Как исправлять - неважно, хоть id припишу.

Нагородить скрипт с циклами можно, но может кто подскажет более элегантное решение?
Каким-нибудь "волшебным" запросом к таблице.

Если предположить что у Вас есть уникальный ID (который легко создать просто добавление поля с автоинкриментом, даже если его нет)


CREATE TEMPORARY TABLE IF NOT EXISTS `tm` (
`hash` varchar(255) NOT NULL
) ENGINE=MyISAM ;
insert into tm select hash from tabl group by hash having count(*)>1;
update tabl set hash=concat_ws(':',hash,id) where hash in (select hash from tm);

Если нужны хэши, можно обернуть concat_ws в md5 понятное дело. Можно даже "посолить" хэши ИД-шником.

iopiop:
1) это где нельзя, в MySQL?
2) операцией сложения добавил к каждой неуникальной строке 2 случайных цифры. или что вы имеете ввиду под "прибил" ?

1) Да. Читайте субж, речь про mysql

2) Операция сложения работает так: 0fbbd14с91d5032e57cb38013a08c793+2 = 2 , поэтому он не прибавит уникальное число к хэшу, а прибьет хэш и пропишет на его место случайное значение от 0 до 100 (что в случае более чем 100 строк гарантированно даже не сделает поле уникальным).

iopiop:
но вообще-то да, неправильно написал, он прибавит к каждой неуникальной :-(, а надо только к одной
ваш update, кстати, тем же болеет ;-)
вот так будет правильнее
insert into tm select max(id) from tabl group by hash having count(*)>1; 

Наш действительно был слегка неверный, Вы правы, сейчас поправили.

Но

insert into tm select max(id) from tabl group by hash having count(*)>1; 
тоже не верно, т.к. одинаковых хэшей может быть больше 1. Правильнее работать напрямую с хэшами при выборке.
Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход. Продаем lenovo legion в спб, дешевле магазинов, новые, запечатанные. Есть разные. skype: edogssoft
I
На сайте с 23.12.2010
Offline
25
#3
edogs:
Во первых, не добавит, потому что апдейт таблицы на которую в этом же запросе делаешь селект - недопустим.
Во вторых, операцией сложения Вы прибили вообще информацию в хэшах.

1) это где нельзя, в MySQL?

2) операцией сложения добавил к каждой неуникальной строке 2 случайных цифры. или что вы имеете ввиду под "прибил" ?

---------- Добавлено в 18:31 ---------- Предыдущее сообщение было в 18:23 ----------

но вообще-то да, неправильно написал, он прибавит к каждой неуникальной :-(, а надо только к одной

ваш update, кстати, тем же болеет ;-)

вот так будет правильнее

insert into tm select max(id) from tabl group by hash having count(*)>1;
zhitov
На сайте с 30.01.2005
Offline
219
#4

Инфа в хеше тут значения не имеет, можно ...c793+2 = c7932

Сначала выберу строки с неуник значениями

select id, hash from table group by hash having count(*)>1;

закину id в массив, затем циклом обновлю hash.

iopiop, edogs, спасибо, что пнули в нужном направлении. :)

I
На сайте с 23.12.2010
Offline
25
#5
закину id в массив, затем циклом обновлю hash.

не получится если больше 2 неуникальных значений, edogs правильно написал последний вариант

вернее получится, но через вложенный селект

SELECT id, hach FROM tbl WHERE hash IN (SELECT hash FROM tbl GROUP BY hash HAVING COUNT(*) > 1);

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий