Avatar billede mousedreamer Nybegynder
26. marts 2011 - 20:03 Der er 4 kommentarer og
1 løsning

opdater tomme felter ved dublet

Hej,

jeg vil gerne lave en tabel med unikke kundeemner og opdatere tomme felter i den unikke tabel hvis dubletten ikke er tom.

Jeg har en kombineret nøgle med navn, adresse, postnr og landekode.

Jeg kan bare ikke finde ud af hvordan jeg opdaterer et felt hvis det er tomt. Her er kommandoen jeg er nået frem til, den mangler at få sidste linje til at virke.

insert ignore
into `tsubject2unique`
select
`id` ,
  `name` ,
  `addressLine1` ,
  `postcode`,
  `city` ,
  `state` ,
  `landlineNo` ,
  `directNo`,
  `cellNo`,
  `employees` ,
  `email` ,
  `www` ,
  `timeStamp` ,
  `countryCode`
from `tsubject` ts
where
ts.`name` not like "" and
ts.`addressLine1` not like "" and
ts.`postcode` not like "" and
ts.`countryCode` not like ""
on DUPLICATE KEY
update `tsubject2unique`.city=ts.city IF ts.city="";
27. marts 2011 - 09:46 #1
Problemstillingen er kompleks.  Lad mig forklare det med mine egne ord.  Saa kan du rette mig hvis jeg har taget fejl. 

Du har en tabel tsubject med kundeemner som indeholder tomme felter og duplikater.  Du vil lave en ny liste i tsubject2unique uden duplikater og med saa komplet information som muligt.

Hvis du koerer din kode bortset fra de sidste to linier og der saa er to raekker i tsubject med samme navn, adresse, postnr, og land, saa faar du overfoert nummer 1, og nummer 2 springes over.

Men hvis nu bynavnet er tomt i nummer 1 men fyldt ud i nummer 2, saa er det den tomme vaerdi du faar overfoert.  Det proever du at rette op paa i de sidste to linier i koden.

Er det korrekt?

Hvis ja, saa tror jeg at jeg har et DELVIST svar:  med INSERT IGNORE ignorerer du duplikater saaledes at ON DUPLICATE KEY ikke leverer nogen vaerdier op!

Om der er en elegant loesning ved jeg ikke (maaske goer andre medlemmer?) men en (ikke saa elegant) mulighed kunne vaere at koere flere queries efter hinanden. 

1.  Foerst koerer du koden uden de sidste to linier.  Saa faar du en ny liste der ignorerer duplikater og vaerdier uden navn, adresse, postnummer, og land, men med mulige tomme vaerdier i andre felter.

2.  Du kan saa erstatte tomme city vaerdier med denne query:

REPLACE INTO tsubject2unique SELECT * FROM tsubject WHERE city not like ""

3.  Og saa hvis du ogsaa vil erstatte tomme emails saa en ny query ....WHERE email not like ""
Avatar billede mousedreamer Nybegynder
27. marts 2011 - 11:50 #2
Det er korrekt forstået, men løsningen 2. og 3.  holder efter min overbevisning ikke, da REPLACE INTO ikke opdaterer, men erstatter hele recorden med en ny, som så igen kan have tomme felter.
27. marts 2011 - 12:25 #3
Jamen det har du da foroevrigt ret i.  Saa jeg har taenkt paa en anden fremgangsmaade, ikke testet:

Foerst koer din kode uden de sidste to linier saa du faar en liste uden duplikater og uden tomme navn/adresse/postnr/land.

Derefter en ny query hvor du finder raekker i tsubject2unique med tomt city og leder efter tilsvarende raekker i tsubject med city fyldt ud -

UPDATE tsubject2unique tu JOIN tsubject ts ON tu.navn = ts.name AND tu.adresse = ts.addressLine1 AND tu.postnr = ts.postcode AND tu.landekode = ts.countryCode SET tu.city = ts.city WHERE tu.city = "" AND ts.city NOT LIKE "";
Avatar billede mousedreamer Nybegynder
27. marts 2011 - 15:50 #4
Ja, det tor jeg vil virke, men her er svaret på mit oprindelige spørgsmål


CREATE FUNCTION getNonEmpty (old VARCHAR(120), new VARCHAR(120))
RETURNS VARCHAR(120)
BEGIN                                     

IF TRIM(old) = '' THEN                 
RETURN new;
else
RETURN old;
END IF;

END;


insert ignore
into `tsubject2unique`
select
`id` ,
  `name` ,
  `addressLine1` ,
  `postcode`,
  `city` ,
  `state` ,
  `landlineNo` ,
  `directNo`,
  `cellNo`,
  `employees` ,
  `email` ,
  `www` ,
  `timeStamp` ,
  `countryCode`
from `tsubject` ts
where
ts.`name` not like "" and
ts.`addressLine1` not like "" and
ts.`postcode` not like "" and
ts.`countryCode` not like ""
on DUPLICATE KEY
update
tsubject2unique.city=`getNonEmpty`(ts.city,tsubject2unique.city),
tsubject2unique.www=`getNonEmpty`(ts.www,tsubject2unique.www);


Må den hurtigste kode vinde, jeg går i gang med at teste lige nu om lidt. Men du skal da have point alligevel, det nytter jo heller ikke at være nærig med point. Hvad synes du om min løsning ?
27. marts 2011 - 16:38 #5
Ok, et svar.  Og hvis din kode virker, saa er det naturligvis det enkleste.  Jeg var overbevist om at 'insert ignore' og 'on duplicate key' ville modvirke hinanden.  Men maaske er det forkert.  Held og lykke med det.
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