26. marts 2011 - 20:03Der 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="";
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 ""
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.
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 "";
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 ?
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.
Synes godt om
Ny brugerNybegynder
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.