Avatar billede 9eller Nybegynder
22. marts 2004 - 15:54 Der er 11 kommentarer og
1 løsning

Dobbelt registrering

Jeg har en tabel hvor der er dobbelt registreringer. Er der nogen der har en nem måde til at rydde op, så der kun er en registrering ?
Avatar billede trer Nybegynder
22. marts 2004 - 16:11 #1
Du skal ind og finde alle dubletter og fjerne dem så der kun er en forekomst.

Nemmeste måde er således

select distinct * into #tempdata from mintabel
truncate table mintabel
insert into mintabel
select * from #tempdata

Ovenstående flytter data fra mintabel over i #tempdata og dropper indholdet i mintabel før den flytter data tilbage.

Har du fremmednøgler mellem "mintabel" og andre tabeller skal de droppes før ovenstående virker.
Avatar billede 9eller Nybegynder
22. marts 2004 - 16:30 #2
Kan man godt bruge * i forbindelse med SELECT DISTINCT ?

Jeg kan ikke få lov til at vælge SELECT DISTINCT * INTO

Får følgende fejl:

Server: Msg 8163, Level 16, State 3, Line 1
The text, ntext, or image data type cannot be selected as DISTINCT.
Avatar billede trer Nybegynder
23. marts 2004 - 08:18 #3
Problemet er, at du har et blob felt (sandsynligvis TEXT) - blob felter kan ikke behandles som "normale" datatyper fordi de kan indeholde 2 GB data.

Hvis du er vant til Access kan det være årsagen til at du har brugt TEXT felter uden egentlig at have behov for det. Dvs hvis du kan leve med mindre datamængder bør du ændre datatypen TEXT til VARCHAR. Når man benytter VARCHAR kan en række dog maks indeholde 8000 bytes.
Avatar billede 9eller Nybegynder
23. marts 2004 - 09:04 #4
Jeg har 31000 rækker i min tabel ...

Er der en anden mulighed for at slette dubletterne uden at lave om på tabellen ?
Avatar billede trer Nybegynder
23. marts 2004 - 09:16 #5
Jah... ved manuel gennemgang...

Men antal rækker er uden betydning - via EM (Enterprise Manager) kan du ændre datatyperne uden at du behøver at gøre noget videre.  Problemet er, hvis du har så meget tekst i et TEXT felt at det ikke kan være i en VARCHAR.

du kan checke længden af data i hver kolonne ved at fyre en sådan sql af

select *
from min tabel
where len(felt)+len(felt)+len(felt)+len(felt) > 7500

det fortæller dig hvilke rækker der kan give problemer (du skal kun gøre det på de felter der indeholder tekstværdier (TEXT, VARCHAR etc).




Men du kan også lige prøve nedenstående

select count(*), felt, felt, felt, felt
from mintabel
group by felt, felt, felt, felt
having count(*)>1

muligvis får du nu en oversigt over de dublerede rækker - eller en fejl igen på dit TEXT felt..
Avatar billede trer Nybegynder
23. marts 2004 - 09:22 #6
Skal lige høre - har du en identity kolonne eller andet der giver dig unik identificering af rækker - eller har du dubletter i alle kolonner i tabellen?
Avatar billede 9eller Nybegynder
24. marts 2004 - 10:31 #7
Det er noget rigtig skidt !

Jeg tror ikke der er unik identificering af rækker, som du skriver. Jeg har prøvet at ændre de 2 text kolonner jeg havde til VARCHAR, og så kan jeg køre :

select distinct * into #tempdata from mintabel
truncate table mintabel
insert into mintabel
select * from #tempdata

Men det ændre ikke noget :o( det er vel osse klart hvis der er sammenfald i flere rækker. Er der kun den manuelle metode tilbage ?
Avatar billede trer Nybegynder
24. marts 2004 - 11:19 #8
Select distinct fjerner dubletter så der kun er en enkelt af de dublerede rækker tilbage. Så hvis ovenstående har kørt kan der ikke være dubeltter tilbage.

Men dublet i ovenstående er en række hvor samtlige felter er dublerede - hvis der er forskel blot i et enkelt felt - f.eks. i milisekunder i et datofelt - så er rækken ikke en dublet!
Avatar billede 9eller Nybegynder
25. marts 2004 - 12:44 #9
Mit problem er (tror jeg), at der ikke har været defineret en primary key på min tabel.

Hvis jeg laver en : select distinct * from mintabel = (29385 row(s) affected)
Hvis jeg laver en : select distinct NAME from mintabel = (19684 row(s) affected)
Avatar billede trer Nybegynder
25. marts 2004 - 12:50 #10
Er det kun udfra name at du skal afgøre om der er dubletter ?
Avatar billede 9eller Nybegynder
25. marts 2004 - 15:26 #11
Ja ... Der må ikke være 2 med samme "name"
Avatar billede trer Nybegynder
25. marts 2004 - 20:11 #12
Okay, jeg er lidt træt, så du får en ikke elegant løsning - men den burde virke


-- opret først tabel magen til "mintabel"
select * into #temp from mintabel where 1=2

-- opret en variabel for hver kolonne i "mintabel"
-- datatyper og navne skal matche kolonnerne
declare @name varchar(50), @col1 int, @col2 int ....

-- opret en cursor der løber gennem "mintabel"
declare crsr cursor local fast_forward for
  select * from mintabel
open crsr
-- hent fra cursor ind i variaberne - husk rækkefølgen skal matche kolonnerne
fetch next from crsr
into @name, @col1, @col2,,,,
-- loop
while @@fetch_status=00 begin
  -- check for dublet og indsæt hvis unik
  if not exists(select 1 from #temp where name=@name) begin
    insert into #temp values(@name,@anything)
  end
  -- som ovenfor -
  fetch next from crsr
  into @name, @col1, @col2,,,,
end
-- luk cursor
close crsr
deallocate crsr
-- hvis output
select * from #temp

-- fjern udkommenteringen hvis alt fungerer
-- truncate mintabel
-- insert into mintabel select * from #temp

Og så vil jeg da foreslå at du lægger en unik constraint på kolonnen "name" - så sker det ikke igen :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester