Gå til innhold

Effektiv metode for å fjerne duplikater i MySql


Anbefalte innlegg

Hve er den mest effektive metoden for å fjerne duplikater fra en MySql tabell?

 

Har en forholdsvis stor tabell som trenger å ryddes for dubbelt oppføringer (duplikater)

 

Kan dette gjøres direkte i SQL query eller børe jeg sette opp litt IF og ELSE logikk?

 

Jeg har sett for meg følgende loop, men er redd den blir treg å kjøre på 200'000 rader.

 

- Hent en rad

- Slett alle like rader

- insert raden på nytt

 

Alle tips mottas med takk.

Lenke til kommentar
Videoannonse
Annonse

Er ingen DB ekspert, men har lekt litt med DBI og MySQL i det siste..

 

Først kan det kanskje være en ide å ta en kopi av tabellen, slik at dersom noe går galt så har du en backup..

 

Opprette en ny tabell og kopierer innhold inn fra gammel tabell:

CREATE TABLE new_tbl SELECT * FROM orig_tbl;

 

Deretter for å luke ut duplikater kan du benytte ID felt i tabell og loope gjennom tabellen, rad for rad, og kjøre en sql for å luke ut duplikater. Noe slik kanskje:

DELETE FROM MYTABLE WHERE kolonne_med_duplikater=$value AND ID!=$id;

 

UPDATE:

$value henter du ut først selfølgelig med en select-sql:

SELECT kolonne_med_duplikater from MYTABLE WHERE ID=$id;

Endret av sam2
Lenke til kommentar

Ok for å oppklare litt:

 

Tabellen inneholder flere kolonner:

 

ID - email - navn - etc -

 

Hvor ID er unik (PRI auto_increment)

 

Problemet er imidlertid at det finnes duplikater i "email" kolonnen, og jeg ønsker å rydde opp i tabellen slik at en email adresse kun skal forekomme en gang.

 

Spørsmålet mitt er egentlig om dette kan gjøres direkte i en SQL query, eller om jeg må sette opp et script med noe som dette:

 

$dbh=DBI->connect($db_name,$db_user,$db_pass);

$sth1 = $dbh->prepare("SELECT email from tablename");

$sth1->execute();

while (($email)=$sth1->fetchrow_array()){

 

$sth2 = $dbh->prepare("delete from tablename where email='$email'");

$sth2->execute();

$sth2->finish();

 

$sth3 = $dbh->prepare("insert into tablename set email=?");

$sth3->execute($email);

$sth3->finish();

 

}

$sth1->finish();

$dbh->disconnect();

Endret av 356speedster
Lenke til kommentar

Tror jeg kom på en mer effektiv metode ved å velge unike email adresser og flytte de til en ny tabell:

 

$dbh=DBI->connect($db_name,$db_user,$db_pass);

$sth1 = $dbh->prepare("SELECT DISTINCT email FROM tablename1");

$sth1->execute();

while (($email)=$sth1->fetchrow_array()){

$sth2 = $dbh->prepare("INSERT INTO tablename2 SET email=?");

$sth2->execute($email);

$sth2->finish();

}

$sth1->finish();

$dbh->disconnect();

 

Men blir dette riktig når jeg skal flytte flere kolonner samtidig?

 

$dbh=DBI->connect($db_name,$db_user,$db_pass);

$sth1 = $dbh->prepare("SELECT DISTINCT(email),variabel1,variabel2 FROM tablename1");

$sth1->execute();

while (($email,$variabel1,$variabel2)=$sth1->fetchrow_array()){

$sth2 = $dbh->prepare("INSERT INTO tablename2 SET email=?,variabel1=?,variabel2=?");

$sth2->execute($email,$variabel1,$variabel2);

$sth2->finish();

}

$sth1->finish();

$dbh->disconnect();

 

Spørsmålet er om denne metoden vil velge kun unike email adresser, og likevel ta med de andre kolonnene, uten å velge kun unike kombinasjoner av alle kolonnene.

Lenke til kommentar

DISTINCT virker på hele raden, slik at:

SELECT DISTINCT(email),variabel1,variabel2

 

og

 

SELECT DISTINCT email,variabel1,variabel2

 

er like.

 

Så, dersom ikke to eller flere rader er helt like så vil du bare hente og legge inn de samme dataene..

-

Dersom du bare skal luke ut rader som har samme email addresse, og det ikke spiller noen rolle hvilke rader du får, kan du benytte GROUP BY slik:

 

SELECT (email,variabel1,variabel2) FROM tablename1 GROUP BY email;

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...