Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Как удалить одинаковые записи в таблице MySQL

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Удаление одинаковых записей(по определённым полям)
AlexGreF
Отправлено: 25 Апреля, 2010 - 17:17:04
Post Id



Новичок


Покинул форум
Сообщений всего: 44
Дата рег-ции: Март 2009  
Откуда: Амурка


Помог: 0 раз(а)




У меня такая задача:
Есть таблица MySQL, например такая:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE IF NOT EXISTS `table` (
  2.   `id` int(11) NOT NULL AUTO_INCREMENT,
  3.   `name` varchar(255) DEFAULT NULL,
  4.   `price` int(11) NOT NULL DEFAULT '0',
  5.   `year` int(11) NOT NULL DEFAULT '1901',
  6.   `probeg` int(11) NOT NULL DEFAULT '0',
  7.   `description` varchar(10000) DEFAULT NULL,
  8.   `city` varchar(255) DEFAULT NULL,
  9.   `phone` varchar(255) NOT NULL DEFAULT '0',
  10.   PRIMARY KEY  (`id`)
  11. ) ENGINE=MyISAM  DEFAULT CHARSET=cp1251;


В таблице более 30 000 строк. Нужно удалить строки с одинаковыми значениями по полям `name`,`year`,`price`,`probeg` и `city`. Причём удалять не все, а последнюю оставлять(ну то есть убрать одинаковые, а оригинал оставить).

Я попробовал сделать так :
PHP:
скопировать код в буфер обмена
  1. $sql = "SELECT `id`,`name`,`price`,`year`,`probeg`,`city` FROM `table`";
  2. $result = mysql_query($sql);
  3. while($ad = mysql_fetch_array($result)){
  4.         $sql = "SELECT `id` FROM `table` WHERE `name`='".$ad['name']."' AND `price`=".$ad['price']." AND `year`=".$ad['year']." AND `probeg`=".$ad['probeg']." AND `city`='".$ad['city']."' AND `id`!=".$ad['id'];
  5.         $rows = @mysql_num_rows(mysql_query($sql));
  6.         if($rows>0){
  7.                 $sames = mysql_query($sql);
  8.                 while($ads = mysql_fetch_array($sames)){
  9.                         echo $ads['id'].'<br>';
  10.                 }
  11.                 echo 'Исходный - <B>'.$ad['id'].'</B><hr>';
  12.         }
  13. }
  14.  


Этот код по идее должен вывести одинаковые строки(`id` строк), но видать памяти не хватает наверно(более 30тыс. строк в таблице), выводит "HTTP-шлюз не отвечает (код ошибки: 504)"

(Отредактировано автором: 25 Апреля, 2010 - 17:17:45)



-----
Моё место во фрилансе - http://weblancer[dot]net/users/alexsava
 
 Top
Champion Супермодератор
Отправлено: 25 Апреля, 2010 - 17:24:56
Post Id



Активный участник


Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008  
Откуда: Москва


Помог: 57 раз(а)




CODE (SQL):
скопировать код в буфер обмена
  1. DELETE FROM tbl t1 WHERE EXISTS (SELECT * FROM tbl t2 WHERE t1.name = t2.name /* и остальное кроме id */ AND t1.id < t2.id)

(Добавление)
Перед удалением делай селект того же самого, что в него попадает точно то, что нужно
 
 Top
AlexGreF
Отправлено: 25 Апреля, 2010 - 19:16:04
Post Id



Новичок


Покинул форум
Сообщений всего: 44
Дата рег-ции: Март 2009  
Откуда: Амурка


Помог: 0 раз(а)




Champion пишет:
CODE (SQL):
скопировать код в буфер обмена
  1. DELETE FROM tbl t1 WHERE EXISTS (SELECT * FROM tbl t2 WHERE t1.name = t2.name /* и остальное кроме id */ AND t1.id < t2.id)

А вто такой запрос тоже должен работать? :
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT *
  2. FROM tbl t1
  3. WHERE EXISTS (
  4.  
  5. SELECT *
  6. FROM tbl t2
  7. WHERE t1.name = t2.name
  8. AND t1.id < t2.id
  9. )
  10. LIMIT 0 , 30

Попробовал такой запрос - та же ошибка, в самом phpMyAdmin - шлюз не отвечает(после долгого раздумывания)
Champion пишет:
Перед удалением делай селект того же самого, что в него попадает точно то, что нужно

Вот это что то не понял..


-----
Моё место во фрилансе - http://weblancer[dot]net/users/alexsava
 
 Top
Champion Супермодератор
Отправлено: 25 Апреля, 2010 - 20:20:52
Post Id



Активный участник


Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008  
Откуда: Москва


Помог: 57 раз(а)




Да, такой запрос должен работать. Ну если таблицу настоящую указать и поля.
А долгое раздумье может быть из-за того, что таблица большая, а индексов нет по нужным полям. В результате приходится на каждую запись проходиться фулл-сканом по всей таблице целиком.
Создай составной индекс по всем полям, по которым сравниваешь, будет быстрее.
 
 Top
AlexGreF
Отправлено: 26 Апреля, 2010 - 04:23:58
Post Id



Новичок


Покинул форум
Сообщений всего: 44
Дата рег-ции: Март 2009  
Откуда: Амурка


Помог: 0 раз(а)




Champion пишет:
Создай составной индекс по всем полям, по которым сравниваешь, будет быстрее.

Если не трудно объясни поподробнее? А то я в MySQL как то не очень в таких тонкостях..


-----
Моё место во фрилансе - http://weblancer[dot]net/users/alexsava
 
 Top
Champion Супермодератор
Отправлено: 26 Апреля, 2010 - 12:53:15
Post Id



Активный участник


Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008  
Откуда: Москва


Помог: 57 раз(а)




CREATE INDEX idx1ef3hxxhfec4de ON tbl (filed1, filed2, filed3, dield4, field5,field6)
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB