webForumDet fria alternativet

Ta bort dubletter

9 svar · 2 471 visningar · startad av antilizaer

antilizaerMedlem sedan apr. 200357 inlägg
#1

Hejsan!

Har suttit och klurat på detta ett tag och vet inte hur man ska lösa det om det överhuvudtaget går. Det jag vill göra är att ta bort dubletter av poster från en tabell, vilka som är dubletter bestäms av deras epostadress, de har dock olika primär nycklar:

    id           email                list_id            
    'e5da-...'   [email]ett@test.se[/email]         'e4fa....'
    'f234-...'   [email]ett@test.se[/email]         'e4fa....'
    'e561-...'   [email]tva@test.se[/email]         'e4fa....'
    '45a1-...'   [email]tva@test.se[/email]         'e4fa....'
    .
    .
    .

Använder mig av MSSQL kolumnerna id samt list_id är av type uniquie identifier, list_id gruppera ihop alla epostadresser som hör till en viss adresslista. Det jag vill göra är att ha kvar en av epostadresserna som finns som dubletter för en viss lista, varje lista kan ha flera dubletta epostadresser som ska bort. Så i exemplet ovan ska det bara finnas kvar en post med epostadress ett@test.se och en med tva@test.se.

Går detta att lösa med en enda SQL sats eller måste man köra med cursors för att lösa det hela.

m_soderlundMedlem sedan sep. 20026 425 inlägg
#2

Du kan använda dig av distinct..

select distinct email from tabell

Jag kommer inte på något bättre sätt, fast det med stor sannolikhet finns. Vänta på någon SQL-guru. ;)

m_soderlundMedlem sedan sep. 20026 425 inlägg
#3

Jag tror att jag kom på en lösning.
Skapa en ny tabell (tabell2) som en kopia av tabellen med alla dubletter (tabell1). Sen kör du denna SQL-fråga:

insert into tabell2
select distinct * from tabell1

Radera tabell1 och byt namn på tabell2 till tabell1.

m_soderlundMedlem sedan sep. 20026 425 inlägg
#4

Ytterliggare ett alternativ som kanske fungerar:

delete from tabell a where tabell a.email = tabell b.email
LarsGMedlem sedan dec. 200012 464 inlägg
#5
delete from t as q
where id not in (
  select min(id) 
    from t
  where t.email = q.email)
antilizaerMedlem sedan apr. 200357 inlägg
#6

Kanske var lite otydlig men jag vill ha kvar den ena av epostadresserna som är dubblett. Så efter jag är klar vill jag att tabellen ser ut så här tex:

id           email               list_id
'e5da-...'   [email]ett@test.se[/email]         'e4fa....'
'45a1-...'   [email]tva@test.se[/email]         'e4fa....'

Går ju att lösa med en cursor som först tar ut vilka addresser som är dubletter och sen tar bort så att bara en av adresserna sen finns kvar, men det jag ville veta var om det går att lösa utan att använda en cursor.

@ndersMedlem sedan juni 200032 969 inlägg
#7

Det är väl det LarsGs kod gör?

antilizaerMedlem sedan apr. 200357 inlägg
#8

Postade mitt inlägg innan jag såg LarsG:s eminenta inlägg, det fungerar dock inte när man använder sig av mssql:s uniqueidentifier pga att det inte går att köra funktionen min() på denna kolumn typ. Inte jag som valt att använda denna kolumn typ i tabellen och nu är det lite sent att ändra på det tyvärr...

Valde att godkänna LarsG inlägg eftersom det gör det jag vill göra om man använder sig av "normala" id kolumner. Tack LarsG

@ndersMedlem sedan juni 200032 969 inlägg
#9

Kan du inte lägga till ett vanligt identity-fält i tabellen då, som du kan köra min() på? Du behöver ju inte förändra någon funktionalitet bara för att du lägger till ett fält i tabellen.

antilizaerMedlem sedan apr. 200357 inlägg
#10

Japp löste det så att jag la till en int kolumn, dock fungerade det inte att sätta "delete from t as q" det klagade på att sätta ett alias på tabellen just för delete, så jag fick sätta ett alias på den inre sql satsen, så här:

delete from t
where id not in (
  select min(id) 
    from t as q
  where t.email = q.email)
128 ms totalt · 3 externa anrop · v20260731065814-full.0e50b1ef
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
125 ms — hämta tråd, inlägg och bilagor (db)