Здравствуйте! Использую следующий запрос для удаления дубликатов из таблицы (он работает): Код (Text): DELETE FROM `table` WHERE id IN ( SELECT * FROM ( SELECT id FROM `table` GROUP BY CONCAT(phone) HAVING count(*) > 1 ) AS a ) можно как-то сделать, чтобы при удалении дубликатов данные из другой колонки в удаленной строке записывались (присоединялись) в другой столбец? например: и т.д., в первых двух номера совпадают, значит один из них будет удалён (кстати- кто?) и мне надо, чтобы в итоге после удаления было так: собственно, как получить дубликаты я знаю. а как сделать конкатенацию? в теории: переписать дублирующие строки с UPDATE (поставить phone на NULL у дубликатов и перенести имя) потом стереть все записи где phone = NULL а в коде не могу сформулировать(
сделать конкатенацию при группировке - group_concat() в твоем примере запрос сделан не по правилам - в списке полей select должны быть только поля из group by или агрегатные функции от других полей. поэтому какой именно id будет выведен невозможно сказать. "not given", как говорят буржуи. можешь писать, например, min(id) тогда будет определенность.
Код (Text): update `таблица` t left join (SELECT max(id) id, phone, group_concat(fio) fio FROM `таблица` group by 2) t1 using(id) set t.phone=t1.phone, t.fio=t1.fio; Среди дубликатов у строки с максимальным id будут сгруппированы fio, у прочих дублей fio и phone будут null (в принципе достаточно выставить у одной колонки). О том как правильно делать группировку см статью Группировка в MySQL Что касается исходного запроса delete, то дубли можно удалять без вложенного подзапроса Код (Text): DELETE t1 FROM t t1 LEFT JOIN t t2 ON t1.col = t2.col AND t1.id < t2.id WHERE t2.id IS NOT NULL;
этот запрос работает, спасибо! Не получалось в одном, убил целый день на поиск работающего метода удаления дубликатов. оказывается, mysql старый- 5.5. обновлять долго. а работает только описанный способ, с вложенностью. просто варианты основаны либо на создании временных таблиц, либо на указании столба с уникальным индексом. у меня ни то ни другое не работает без ошибок. я ещё с альясами ещё не разобрался. если несложно. адаптируйте названия полей в вашем примере к моей задаче, попробую выполнить. вдруг заработает) таблица- `tbl`, колонки: id, phone, fio
Ещё как получается, указанный запрос удаляет из таблицы t (у вас tbl) дубликаты (строки с одинаковыми значениями поля col (у вас phone)) с меньшим id (у вас тоже id). Обновлять не надо, в новых версиях тоже самое ограничение.
ха.. действительно работает. ну где-то что-то пропустил наверное. спасибо! и ещё вопрос по объединению строк. допустим, исходное содержание таблицы такое: Код (Text): id phone fio address 1 898989 Иванов Москва 2 898989 Иванов СПБ 3 787878 Петров СПБ 4 989898 Сидоров НН 5 989898 Кузнецов Москва выполняем запрос конкатенации, получили: Код (Text): id phone fio address 1 898989 Иванов,Иванов Москва 2 787878 Петров СПБ 3 989898 Сидоров,Кузнецов НН здесь удалены дубликаты столбца phone у г-на Иванова, в fio прописалась его фамилия. но! она не должна повторять то, что уже есть в поле. только если там другое значение, например- Кузнецов. и ещё есть один столбец- address, там в процессе объединения тоже должна производиться конкатенация по такому же принципу. в общем, мне нужно получить вот такой результат: Код (Text): id phone fio address 1 898989 Иванов Москва, СПБ 2 787878 Петров СПБ 3 989898 Сидоров,Кузнецов НН, Москва
Код (Text): update tbl t left join (SELECT max(id) id, phone, group_concat(distinct `fio`) fio, group_concat(distinct `address`) address FROM tbl group by 2) t1 using(id) set t.phone=t1.phone, t.fio=t1.fio,t.address=t1.address; вроде так работает) только сделал мне несколько пустых строк((
В смысле пустых? У дубликатов с меньшим id поля phone, fio и address будут null. В принципе null достаточно выставлять одному полю, всё равно их потом удалять.
а, ну если потом удалять, то норм. Здесь null присваивается? t.fio=t1.fio,t.address=t1.address у меня удаление отдельной командой, а слияние контактов- отдельной.
а ещё маленький вопросик, тоже вроде простой, но что-то не нашёл сам решения. в общем, есть ещё один столбец, называется status. мне нужно, чтобы слияние и удаление действовали только для status=0, а всё остальное- без изменений. полагаю, что где-то в конце запроса нужно вставить WHERE status=0, но пока у меня не сработало. подскажите, где поставить условие.
так вот и не могу понять, куда вставлять-то это условие(( Код (Text): update tbl t left join (SELECT max(id) id, phone, group_concat(distinct `fio`) fio, group_concat(distinct `address`) address FROM tbl group by 2 WHERE `stastus`=0) t1 using(id) set t.phone=t1.phone, t.fio=t1.fio,t.address=t1.address WHERE `stastus`=0; DELETE t1 FROM tbl t1 LEFT JOIN tbl t2 ON t1.phone = t2.phone AND t1.id < t2.id WHERE (`status`=0 and t2.id IS NOT NULL);
правильная последовательность фраз в одном запросе (что-то может отсутствовать, менять местами нельзя): Код (Text): SELECT FROM WHERE GROUP BY HAVING ORDER BY LIMIT