Пометить дубли в MySql таблице

Lexx59

Профессор
Регистрация
9 Янв 2009
Сообщения
183
Реакции
38
Помогите решить.
Есть mysql табличка на 2353 элементов.
В табличке помимо прочих есть поля: "URL" и "isdubl"
У некоторых записей URL совпадают.
Для всех записей где URL не уникальный надо присвоить "isdubl=`1`"
 
SELECT `URL`
FROM `table`
GROUP BY `URL`
HAVING ( COUNT(`URL`) > 1 )

выдаст все дубли URL.
 
PHP:
<?php
//Данные для подключения к БД
$host="localhost";				// Имя хоста
$bdname="baza";				// Имя БД
$bdlogin="baza";				// Логин к БД
$bdpassword="parol";		// Пароль к БД

$db=@mysql_connect($host,$bdlogin,$bdpassword);
if(!$db)die(mysql_error());
if(!@mysql_select_db($bdname,$db))die(mysql_error()); 
$query_dubl=mysql_query("SELECT * FROM tablica ",$db);
while($urls=mysql_fetch_array($query_dubl)){
$query_dubl2=mysql_query("SELECT * FROM tablica WHERE URL = '".$urls['URL']."'" ,$db);
if(mysql_num_rows($query_dubl2)==1)
{echo "совпадений нет <br> ";
}else {$update=mysql_query("UPDATE tablica SET isdubl='1' where URL = '".$urls['URL']."'",$db);}
}
?>
 
получаешь идентификаторы записей с урлами, они будут выступать как не-дубли:
Код:
SELECT DISTINCT `id` FROM `test` GROUP BY `url`
Такой селект выберет из нескольких одинаковых записей один id как уникальный, правильно? А надо пометить все дубли, чтобы потом выбрать из них наилучшую запись.

далее обновляешь поле "isdubl" у всех записей кроме этих выбранных:
Код:
UPDATE test SET is_dubl = 1 WHERE id NOT IN 'тут твои айдишники'
p.s. одним запросом такое реализовать не получится, т.к. mysql не разрешает использовать 1 и ту же таблицу одновременно для чтения и записи.
Да. Вот это главное препятствие. Никак не могу понять эту парадигму.
Вроде все просто - выбрать неуникальные и обновить поле.
Код:
UPDATE `isdubl`=1 from `table` where
(
SELECT `URL`
FROM `table`
GROUP BY `URL`
HAVING ( COUNT(`URL`) > 1 )
)

Тут получается нужно вначале сделать select, а потом в цикле выбирать по одному URL и апдейтить.
Хотя лучше ч\з дополнительную табличку сделать.

Как вначале все URL этого запроса внести во вспомогательную table2
Код:
SELECT `URL`
FROM `table1`
GROUP BY `URL`
HAVING ( COUNT(`URL`) > 1 )

А потом проапдейтить
Код:
UPDATE `table1` SET `is_dubl` = 1 WHERE URL IN 'Все значения URL из table2'
?
 
Все делается одним запросом:
Код:
UPDATE `test` SET `is_dubl` = 1 WHERE `url` IN(SELECT `url` FROM (SELECT * FROM `test` GROUP BY `url` HAVING (COUNT(`url`) > 1)) AS `temp`)
 
можно не делать select * , так как работаем только по одному полю:
UPDATE `test` SET `is_dubl` = 1 WHERE `url` IN(SELECT `url` FROM (SELECT `url` FROM `test` GROUP BY `url` HAVING (COUNT(`url`) > 1)) AS `temp`)
 
можно не делать select * , так как работаем только по одному полю:
UPDATE `test` SET `is_dubl` = 1 WHERE `url` IN(SELECT `url` FROM (SELECT `url` FROM `test` GROUP BY `url` HAVING (COUNT(`url`) > 1)) AS `temp`)
а можно написать хранимую процедуру, это уже вопрос оптимизации и в рамках поставленной ТС задачи роли не играет.
 
Все делается одним запросом:
Код:
UPDATE `test` SET `is_dubl` = 1 WHERE `url` IN(SELECT `url` FROM (SELECT * FROM `test` GROUP BY `url` HAVING (COUNT(`url`) > 1)) AS `temp`)
То что надо. Так и знал что есть красивое и элегантное решение в одну строчку.
 
Хочу удалить дубли в таблице, но не выходит выполнить запрос.

`item` - таблица
`id` - уникальный идентификатор записи в пределах таблицы
`h_all` - md5 хеш по которому проводиться поиск дублей


PHP:
DELETE FROM `item` WHERE `id` NOT IN(SELECT MIN(`id`) FROM `item` GROUP BY `h_all`)

Выдает:
1093:You can't specify target table 'item' for update in FROM clause


Подскажите что не так.
 
Это не баг, а блокировка целостности.
Читайте документацию. Надо 2 запроса. Первым - создаем табличку с теми Id, которые надо удалить. Вторым - удаляем. Как бы вам не хотелось одним запросом удалить - не получится.
 
Назад
Сверху