Dubletter i MySQL-databaser.

Tags:    databaser

Hej udviklere,

Jeg står med en database der indeholder uoverkommeligt mange rækker og har fået et indtryk af, at den indeholder dubletter, hvilket i mit tilfælde er temmelig nødvendigt at få elimineret.

Jeg har søgt på emnet på internettet naturligvis, men det er ikke lykkedes mig at komme frem til en SQL-forespørgsel der returnerer de dubletter, jeg leder efter.

Min database med navnet rank er bygget om som følger:
ID - UID - NAME - PICTURE - LINK - RANK:
1 - 23 - Lars - http://...- http:// - 2
1 - 24 - Peter - http://...- http:// - 2
1 - 23 - Lars - http://...- http:// - 2
1 - 26 - Lasse - http://...- http:// - 2

Ovenstående data er blot eksempler, men de giver dog et indtryk af, hvordan min tabel ser ud.

Mit problem ligger i, at jeg skal have fundet ud af, hvornår navn og UID går igen, og det er indtil videre ikke lykkes mig, derfor har jeg kraftigt brug for jeres hjælp! :-)

Alt det bedste,
Mathias.




Mener at det er noget lign. dette du skal bruge for at finde dubletter frem.
Fold kodeboks ind/udSQL kode 




Indlæg senest redigeret d. 03.11.2010 20:58 af Bruger #10216
Jeg tror umiddelbart, at du er inde på noget af det rigtige, men forespørgslen finder ikke frem til nøjagtigt det output, jeg søger.

Fx kan jeg i min database se, at der er tre personer med navnet "Kemp Peterson", men findes der en måde, hvorpå den finder frem til de to dubletter, således at man bare kan markere alle rækkerne og udrydde dubletterne på den måde, mens man stadigvæk efterlader den oprindelige række, hvori navnet "Kemp Peterson" indgår? Giver det mening?



Hvis ikke det skal i noget virkelig kryptisk SQL, så vil jeg nok nøjes med ovenstående.

Du kan jo udvide den til
Fold kodeboks ind/udSQL kode 


Skriv en stump kode i dit serversprog der gennemløber resultatet og afvikler en SQL-streng for hver række:
Fold kodeboks ind/udSQL kode 

Dollartegnet er variabler fra din kode, som matcher uid og cnt felterne i tidligere resultat.



Ellers kan denne måske virke - prøv dog med select inden du afvikler en delete
Fold kodeboks ind/udSQL kode 




I dit eksempel har du skrevet id=1 i alle rækkerne, men er id ikke et unikt id? Hvis hver enkel id er unik kan du vælge de to "Kemp Peterson"-rækker med en id der er større end den originale "Kemp Peterson"-række:
Fold kodeboks ind/udKode 




Jo. Det er lige nøjagtigt den korrekte forespørgsel, du har fat i! Tusind tak for hjælpen.



Når jeg forsøger at slette de resultater der dukker op i phpMyAdmin returnerer siden blot følgende fejl, "#1054 - Unknown column 'r1.id' in 'where clause' " og "DELETE FROM `rank`.`rank` WHERE `r1`.`id` =171". Problemet er tydeligvis r1 som ikke eksisterer i tabellen, men så vidt jeg kan se er med til at give de korrekte dubletter i selve forespørgslen. Har I nogle gode fif til, hvorledes man lige kringler den?



Jeg tror måske mit forslag har forvirret mere end det gavnede. Hvis det ikke er vigtigt at det er rækken med det laveste id der bliver gemt, er Michael Larsens løsning (03-11-2010 22:00) mere elegant. Den kræver dog to rettelser. For det første skal der grupperes efter både uid og name. For det andet kan man (i MySQL) ikke lave en subquery på en tabel man sletter fra. Hvis du vil undgå at bruge et server-side script kan du udføre følgende tre kommandoer (husk at lave en backup af hele din tabel inden!):

Først laver du et view med id'erne på alle de rækker du vil beholde:
Fold kodeboks ind/udKode 


Derefter sletter du alle rækker fra rank hvis id ikke findes i viewet:
Fold kodeboks ind/udKode 


Og til sidst kan du slette viewet igen:
Fold kodeboks ind/udKode 




Indlæg senest redigeret d. 04.11.2010 10:42 af Bruger #13559
Nu virkede det omsider, så jeg takker jeg begge ærbødigt! Det var lige, hvad jeg havde brug for.



t