Чистене на дублирани записи но запазване на 1

  • Автор Автор Hous
  • Начална дата Начална дата

Hous

Registered
Онзи ден доста ровене и опити направих за подобна заявка, трябва ми заявка която при примерно 3 еднакви записа (без значение големи/малки букви) да чисти 2 и да остави 1 със най-малкото id.
Пробвах доста каквото се сетих и каквото намерих но в крайна сметка заявките се получиха по 30-60 секунди и накрая почти никакъв резултат, понякога губих цялата таблица...
записите са над 30 000 а имам около 500 повтарящи се...
Ако някой мжое да помогне. :)
пс:става дума за повтаряне не на всички колони а само на полето description
 
Да пробвах ги , някой блокираха нацяло ,други забавяха по 2-3 минути и някрая или нищо не ставаше или се триеха абсолютни всички записи...

С ето тази заявка обаче успвам да намеря всички дублирани записи(само,че имат значение малка/голяма буква)
Код:
SELECT * FROM products
INNER JOIN (SELECT description FROM products
GROUP BY description HAVING count(id) > 1) dup ON products = dup.description
Ако може да покажете пример с нея примерно със lower и delete + нея, мисля,че ще ми свърши работа...
 
Hous каза:
С ето тази заявка обаче успвам да намеря всички дублирани записи(само,че имат значение малка/голяма буква)
колация?!?

Hous каза:
Ако може да покажете пример с нея примерно със lower и delete + нея, мисля,че ще ми свърши работа...

[sql]DELETE products.* FROM products,
(SELECT LOWER(IFNULL(description,'')) Z,
COUNT(id) X,
MIN(id) Y FROM products
GROUP BY 1
HAVING X>1) dup
WHERE LOWER(IFNULL(products.description,''))=dup.Z
AND products.id<>dup.Y;
[/sql]
п.п.: налага се да излизам, затова ако има още нещо ... по-късно :?:
 
Най-лесния workaround :D

[sql]ALTER IGNORE TABLE tablica ADD UNIQUE (pole_koeto_iskash_da_e_bez_duplikati);[/sql]
 
Пффффффффф , играчка-плачка както са казали :D
от тестване бъгнах целия сървър , сега дори сайта не зарежда, май от хостинга ще ми се накарат :oops:

Иначе ще тествам предложенията веднага след като се оправи съврърът... :D :)
 
deam0n каза:
Най-лесния workaround :D

[sql]ALTER IGNORE TABLE tablica ADD UNIQUE (pole_koeto_iskash_da_e_bez_duplikati);[/sql]
SQL заявката беше изпълнена успешно ( Заявката отне 318.1987 секунди )
:D
Ужас, тъкмо си казвах "айде пак отиде" :D
edit:Останаха дублирани записи със разлика в големината на буквите, пример:
пешо Иванов
Пешо ИВАНОВ

се разчитат като различни записи ... и сега пак има повторения (по-малко) но все още стоят ... някаква идея за тях?
Освен да пробвам и заявката на Koko?
 
ALTER IGNORE TABLE tablica ADD UNIQUE (LOWER(pole_koeto_iskash_da_e_bez_duplikati));



Така би трябвало да стане. Прави полето да е lower case.
 
Hous каза:
Освен да пробвам и заявката на Koko?
Това е наистина добра идея :lol:
Аз съм я тествал и е ок.
Проблема с регистъра ще го решиш с избора на подходящата колация, а тя трябваше да бъде променена преди добавянето на уникалния ключ... Предполагах, че има причина полето да не е уникално, затова написах заявката така, че да се справи и с неуникално поле (с DEFAULT NULL) с чувствителна към регистъра колация.
Хмм, нямаш ми доверие, но все пак опитай :)
п.п.: преди заявката трябва да сетнеш connection pipe, т.е. SET NAMES UTF8 да речем.
п.п.2: видях, че deam0n ти е дал идея пак-така ще стане за момента, но в бъдеще, ако няма подходящата колация, уникалния ключ ще позволи да се добави Пешо ИВАНОВ въпреки, че пешо Иванов вече е въведен. Тогава опираме пак до моята заявка, въпреки UNIQUE KEY.
 
Не че нямам доверие просто както споделих на два пъти бутнах сървъра ... и някак спрях да тествам каквото и да е ... ще върна бакъпа с оригиналните записи както бяха преди последната заявка от daemon , ще пробвам както казваш...
ще пробвам и на daem0n методът с lower пък което стане в моя случай, само,че ще пиша малко по-късно с инфо какво е станало. :)
 
@koko мисля,че почти същото нещо стана , изтрити 394 реда, а по принцип дубликатите са към 500++


със unique Ключа стана, то за напред няма да има дубликати , защото таблицата ми е дадена така готова ... но въпроса е за момента че каквото и да пробвам всички остава поне половината от повтарящите се, едно че оставя записи от типа :
Ива Танева
Ива танева
като различни, друго че има абсолютно единтични:
Бла бла
Бла бла
които пак стоят...

колацията и връзката е utf-8 , не знам дали в самата заявка трябва да задавам допълнително параметрите за utf-8 и дали са от значение...
 
Заявката работи перфектно в случая, който си споменал. Сигурно имаш интервали или друг специален символ, но ако е само за "Иван" и "иван" съм я тествал и работи. Трябва да се добави и trim
[sql]
DELETE products.* FROM products,
(SELECT TRIM(LOWER(IFNULL(description,''))) Z,
COUNT(id) X,
MIN(id) Y FROM products
GROUP BY 1
HAVING X>1) dup
WHERE TRIM(LOWER(IFNULL(products.description,'')))=dup.Z
AND products.id<>dup.Y;
[/sql]
Колацията ти е да речем utf8_unicode_ci, a ти си я избрал cs, за да прави този номер.
Example: [sql]CREATE TABLE t1(
s varchar(255) character set utf8 collate utf8_unicode_ci
default null)[/sql]CI значи Case Insensitive, a CS -> Case Sensitive.
 
Има логика и ще го запомня,при заявката за търсене примерно ползвам lower() и си работи без проблем...

иначе проверих и самата колация си е CI :х
Мисля да го зарежа и толкова... не видях да има специални символи , празно място и тн... не знам къде е проблема.Ако някой има идея да сподели ако не просто ще го оставя така и т'ва е.

Благодаря за идеите иначе. :)
 
Не съм убеден, но е възможно phpMyAdmin да добавя LIMIT за update/delete зарази safeguard options, особено на shared host. Опитай с дъмп на localhost u c console.
Другия вариант е да изпълняваш заявката докато даде 0 rows affected. To ако при две последователни заявки трие още записи на втората, значи наистина добавя лимит, а не че не открива еднаквите :?:
 

Back
Горе