Avatar billede michaeljuhl Nybegynder
07. november 2009 - 10:45 Der er 12 kommentarer og
1 løsning

Update TB med nye data

Hej, er der en der kan hjælpe mig med følgende spørgsmål:
Jeg har tabel med 3 felter som:


id,name,truefalse
1,01,true
1,02,false
1,03,true
1,04,true
1,05,false
2,01,false
2,02,false
2,03,false
2,04,false
2,05,false

Det jeg ønsker er at tage de records med id=1 samt truefalse=true
og opdatere tilsvarende records id=2 med samme name til at være = truefalse

Resultat skulle blive :
id,name,truefalse
1,01,true
1,02,false
1,03,true
1,04,true
1,05,false
2,01,true <opdateret
2,02,false
2,03,true <opdateret
2,04,true <opdateret
2,05,false

Med venlig hilsen
Michael
Avatar billede michaeljuhl Nybegynder
07. november 2009 - 10:49 #1
Hej jeg glemte at sige at dette skal opdateres en gang om dagen, så hvis hjælpen kan blive med en løsning i form af en Stored Procedure, vil det hjælpe mig meget :-)
Tak på forhånd.
Michael
Avatar billede janus_007 Nybegynder
07. november 2009 - 11:55 #2
hmm sådan lige skrevet ud af hovedet er det vel noget i stil med:

update Tabel set truefalse = t.truefalse from Tabel t
inner join Tabel t1
on t1.Name = t.Name
where t.Id = 1 and t.truefalse = true
and t1.Id = 2
Avatar billede michaeljuhl Nybegynder
07. november 2009 - 12:40 #3
Okay Janus_007 det virker, så smid et svar, så jeg kan give dig point
Hvis du skulle lave det i en SP, har du så også en løsning til det :-)
//Michael
07. november 2009 - 15:44 #4
michaeljuhl og janus - jeg er i faerd med at laere mig selv mysql/php/css og lidt mere.  Jeg har fundet det meget laererigt at studere de spoergsmaal der kommer her paa eksperten, proeve at finde svar, og hvis det ikke lykkes saa at studere de svar der kommer.

Jeg var igang med at kikke paa dette spoergsmaal og gik ud fra at det skulle loeses ved hjaelp af et sub-query - saasom "update table set truefalse = true where id = 2 and name IN (select name from tabel where where id = 1 and truefalse = true)" men det kunne jeg ikke faa til at virke (jeg arbejder i phpmyadmin gennem one.com), heller ikke hvis jeg bruger tabel t og tabel t1.  Google synes at mene at mysql ikke tillader at bruge samme tabel i subquery som den tabel man vil update. 

Mens jeg saa arbejdede med en "workarouond" (som jeg giver nedenfor) kom janus med sit meget enklere svar.  Det finder jeg interessant.  Men jeg kan ikke faa det til at virke.  Hvis jeg skriver det i phpmyadmin faar jeg en fejlmelding at der er syntax fejl near "from Tabel t..."  Det synes som om min version af mysql ikke vil acceptere konstruktionen "set truefalse = t.truefalse from ...."

Janus, du siger at din kode er "skrevet lige ud af hovedet."  Er der en syntax fejl smutted ind i skyndingen eller virker det noejagtigt som skrevet og det burde kunne virke hos mig ogsaa?  I saafald, er der et triks jeg har overset saasom at skulle skifte delimiter:

Janus, det er egenligt et nyt spoergsmaal, men jeg var bange for at sammenhaengen ville gaa tabt hvis jeg stillede det som et nyt spoergsmaal, men hvis du kan give mig et svar vil jeg lave en "Points til Janus" med 60 points.

Det jeg selv fandt frem til var at "snyde" mysql ved at lave en ny tabel der er en kopi af de raekker i den oprindelige tabel hvor id = 1 og truefalse = true og saa bruge denne tabel i subquery.  Jeg fandt frem til en stored procedure som jeg har testet mod en tabel ved navn michaeljuhl som jeg lavede med de ovenstaaende vaerdier.  Naar jeg kalder den storede procedure resulterer det i de rigtige updates.

Her er foerst resultatet af SELECT * FROM michaeljuhl
id  name  truefalse 
      1 01 1
      1 02 0
      1 03 1
      1 04 1
      1 05 0
      2 01 0
      2 02 0
      2 03 0
      2 04 0
      2 05 0

Her er saa min stored procedure:

CREATE PROCEDURE updatetable()
BEGIN
  CREATE TABLE michaeljuhl1 AS SELECT * FROM michaeljuhl WHERE id=1 AND truefalse = true;
  UPDATE michaeljuhl SET truefalse = true WHERE id = 2 AND name IN (
    SELECT name FROM michaeljuhl1);
  DROP TABLE michaeljuhl1;
END

(delimiter saettes til $ foer prodeduren oprettes og tilbage til ; derefter.)

Efter jeg kalder proceduren med "call updatetable" faar jeg den foelgende tabel hvor truefalse er rettet:

id  name  truefalse 
      1 01 1
      1 02 0
      1 03 1
      1 04 1
      1 05 0
      2 01 1
      2 02 0
      2 03 1
      2 04 1
      2 05 0
Avatar billede michaeljuhl Nybegynder
07. november 2009 - 18:30 #5
Hej Christian

Jeg rettede lidt i Janus løsning, og derefter virkede det

Brug tabel alias t i starten af syntaksen

Update t set truefalse =
eller brug kun tabel alias på t og skriv det originale tabel navn der hvor aliaset T1 blive brugt, så virkede det

update Tabel set truefalse = t.truefalse from Tabel t
inner join Tabel t1
on t1.Name = t.Name
where t.Id = 1 and t.truefalse = true
and t1.Id = 2

Håber du kan bruge det :-)

Jeg håber ikke det gør noget jeg lige skriver dette Janus :-)
Avatar billede janus_007 Nybegynder
07. november 2009 - 18:45 #6
michaeljuhl ->

Ja en stored procedure er nu kun et par ekstra linjer..

se her:

create proc spSomeName
as
begin

--skriv din kode her :)

end
Avatar billede janus_007 Nybegynder
07. november 2009 - 19:00 #7
Christian_Belgien -> Ja det er også en måde at gøre det på, jeg bruger dog sjældent subqueries på måde fordi det ikke er muligt at lave flere IN's

Jeg kan ikke rigtigt se dit spørgsmål?

Men....

  UPDATE michaeljuhl SET truefalse = true WHERE id = 2 AND name IN (
    SELECT name FROM michaeljuhl1);
  DROP TABLE michaeljuhl1;

Hvis nu denne skulle skrives hvor både 'name' og måske 'lastname' skulle være 'IN' så var man ikke sikret korrekt UPDATE på rækkeniveau.

Den update join jeg har skrevet kan også skrives uden inner join, som en slags hybrid imellem subquery og join.

update Tabel set truefalse = (select truefalse from Tabel
where Name = t.Name where Id = 1 )
from Tabel t
where Id = 2


Men jeg sidder og tænker på om I bruger MySQL?
Avatar billede janus_007 Nybegynder
07. november 2009 - 19:01 #8
:)
07. november 2009 - 20:11 #9
Da jeg engang i et tidligere aarhundrede boede i Danmark var der en der hed Spoergejoergen.  Det er der maaske stadigvaek?  Og maaske har jeg arvet fra ham (maaske er det ikke for ingenting at jeg hedder Joergen-sen.)  Saa, spoergsmaal/kommentarer:

Janus, du siger:  "Men jeg sidder og tænker på om I bruger MySQL?"  Er det fordi du ikke bruger mysql og det virker fint med hvad du bruger?  Jeg bruger mysql, og din kode med subquery stoeder paa det samme problem som mit oprindelige forsoeg:  mysql stoetter ikke at man i update laver en subquery paa den samme tabel som den man vil update.  Jeg fandt, efter lang soegen, denne udtalelse (i mysql sammenhaeng):  "There is one caveat: It is not currently possible to modify a table and select from the same table in a subquery." (Source http://dev.mysql.com/tech-resources/articles/4.1/subqueries.html.)  Det skal muligvis vaere lignende mysql begraensninger der goer at jeg ikke kan bruge "update Tabel set truefalse = t.truefalse from Tabel t..." og lignende formuleringer.  Saa Janus, Michael, bruger i en SQL forskellig fra mysql og virker det der.  (Hvis i bruger mysql og har faaet det til at virke der saa er jeg tilbage til udgangspunktet.)

Janus, saa siger du at min stored procedure maaske ikke virker hvis der skal matches for eksempel til et name og et lastname.  Jeg proevede.  Jeg lavede en lastname kolonne i tabel michaeljuhl og omskrev den storede procedure til det nedenstaaende og ved at kalde den fik jeg den korrekte update.  Her kommer den:

CREATE PROCEDURE updatetable()
BEGIN
  CREATE TABLE michaeljuhl1 AS SELECT * FROM michaeljuhl WHERE id=1 AND truefalse = true;
  UPDATE michaeljuhl SET truefalse = true WHERE id = 2 AND (name, lastname) IN (
    SELECT name, lastname FROM michaeljuhl1);
  DROP TABLE michaeljuhl1;
END
Avatar billede michaeljuhl Nybegynder
07. november 2009 - 21:55 #10
Hej Janus

Tak for dine svar, de kunne alle bruges

PS: Jeg bruger MS SQL 2005

Venlig hilsen
Michael
Avatar billede janus_007 Nybegynder
07. november 2009 - 23:02 #11
Ja jeg har sjældent arbejdet med MySQL, sidder fortrinsvis med SQL Server fra Microsoft. Jeg ved at der er forskelligheder, men hvilke aner jeg ikke :) Det her var så en af dem!

Den syntax med " (name, lastname) IN (
    SELECT name, lastname.."
har jeg aldrig set før og kan heller ikke lade sig gøre i MSSQL, forunderligt :) Men godt I fik det hele til at fungere :)
08. november 2009 - 05:53 #12
Janus, det kursus jeg havde i sql for adskillige aar tilbage (paa afstandsundervisning ved det hollandske "Open Universiteit") brugte et sql program der hed InterBase (nok fordi det var gratis og mysql ikke bestod endnu).  Kurset sagde at i tilfaelde af subselects med en bred noegle var den teoretisk rigtigt loesning den med (name, lastname) IN ... men at InterBase desvaerre ikke kunne.  De brugte derfor Oracle for at demonstrere.  I Interbase skulle vi bruge "WHERE name || "-" || lastname IN (SELECT name || "-" || lastname FROM ...)".  Da jeg fornyligt fandt det gamle kursus frem proevede jeg de forskellige oevelser af i mysql.  name || "-" || lastname virker saa tilgaengaeld ikke i mysql (eller jeg har ikke kunnet finde ud af det), her skal man bruge CONCAT(name, "-", lastname).

Jeg sagde at jeg ville give points for din hjaelp selv om jeg broed ind i en anden's spoergsmaal, og du har leveret svaret paa mit problem, at jeg skal vaere opmaerksom paa forskellene mellem de forskellige sql programmer, og jeg fik yderligere udbygget min kendskab.  Mogens ogsaa tak fordi du lod mig bryde ind.
Avatar billede michaeljuhl Nybegynder
08. november 2009 - 09:07 #13
Hej Christian

No problem, det gør du bare en gang igen hvis du skulle have lyst til det :-)

//Michael
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