1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

update set CASE WHEN - wie geht das?

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von michaldo, 14 März 2012.

  1. michaldo

    michaldo Benutzer

    Ich habe ein Problem das ich einfach nicht in den Griff bekomme.
    In einer MySQL 5 DB sollen Datensätze upgedated werden.
    Es gibt einen Array von ids und ein anderes Array mit Werten.
    Alles soll mit einem Zugriff gemacht werden also ohne Schleife.

    Mein bisheriger code sieht folgendermaßen aus.

    Code:
    sprintf("UPDATE `%s` SET sumL = CASE WHEN '%s' THEN '%s' ELSE '0' END WHERE id '%s'", $db,  implode("', '", $id), implode("', '", $anzL ),  implode("', '", $id) );
    und so wie unten sieht der daraus entstehende Aufruf aus. Ich habe hier viele Werte herausgenommen wegen der bessern Lesbarkeit. Es sind in Wirklichkeit viele Datensätze.

    Code:
    UPDATE `besucher` SET sumL = CASE WHEN '1', '5', '7', '12', '19', '32' THEN '11', '2', '3', '24', '5', '1', ELSE '0' END WHERE id '1', '5', '7', '12', '19', '32'
    Ich habe schon alle Varianten mit Klammer und Hochkomma und ohne alle ausprobiert aber es funktioniert nicht.
     
  2. ukulele

    ukulele Datenbank-Guru

    Ich denke mal das das mit der Werteliste im THEN Bereich nicht funktioniert, da wird vermutlich nur ein Wert gehen der gesetzt wird, wenn die Bedingung davor wahr ist. Probiers mal so, auch wenn es zur Erstellung aufwendiger ist:
    Code:
    UPDATE    `besucher`
    SET        sumL = (    CASE sumL
                        WHEN '1'    THEN '11'
                        WHEN '5'    THEN '2'
                        WHEN '7'    THEN '3'
                        WHEN '12'    THEN '24'
                        WHEN '19'    THEN '5'
                        WHEN '32'    THEN '1'
                        ELSE '0'
                        END )
    WHERE    id IN ( '1', '5', '7', '12', '19', '32')
     
  3. michaldo

    michaldo Benutzer

    Hallo ukulele,
    Das sieht zwar cool aus aber ich habe keine Ahnung wie ich das in einem Aufruf hinbekommen soll.
    Beide Werte, also das WHEN das die betroffenen ids darstellt und auch das THEN das den neuen Wert enthält sind so gut wie bei jedem Aufruf verschieden. Da es im schlimmsten Fall gut 800 Einträge wäre möchte ich es wenn möglich nicht in einer Schleife machen. Mit einer Schleife wäre es leicht das zu machen allerdings wird eben dabei die DB regelrecht bomadiert und dass wohl alle paar Minuten.
    Das IN funktioniert in diesem Fall wohl nur im WHERE clause soviel ich jetzt erkannt habe.
    Wenn ich also den Aufruf so schreibe funktioniert er nicht.
    Code:
    sprintf("UPDATE `%s` SET sumL = (CASE sumL
                                   WHEN '%s' THEN '%s' ELSE '0' END)
                                   WHERE id IN '%s'",
                                   $db,  implode("', '", $id), implode("', '", $anzL ),  implode("', '", $id)  );
    Wie könnte ich das doch noch in einem Aufruf ohne Schleife realisieren?
     
  4. ukulele

    ukulele Datenbank-Guru

    Das IN funktioniert auch im WHEN Teil, allerdings muss man bei der CASE Anweisung eine Sache beachten:

    Schreibe ich CASE feld WHEN wertalt THEN wertneu END, geht das. Ist meine Bedingung irgendetwas anderes als =, z.B. IN, muss ich das anders aufbauen: CASE WHEN feld = wertalt THEN wertneu END oder CASE WHEN feld != wertalt THEN wertneu END oder CASE WHEN feld IN werteliste THEN wertneu END, etc.

    Es müsste also folgendes gehen:
    Code:
    UPDATE    `besucher`
    SET        sumL = (    CASE
                        WHEN sumL = '1'        THEN '11'
                        WHEN sumL = '5'        THEN '2'
                        WHEN sumL = '7'        THEN '3'
                        WHEN sumL = '12'    THEN '24'
                        WHEN sumL = '19'    THEN '5'
                        WHEN sumL = '32'    THEN '1'
                        ELSE '0'
                        END )
    WHERE    id IN ( '1', '5', '7', '12', '19', '32')
    oder auch
    Code:
    UPDATE    `besucher`
    SET        sumL = (    CASE
                        WHEN sumL IN ( '1', '5', '7', '12', '19', '32')    THEN '11'
                        ELSE '0'
                        END )
    WHERE    id IN ( '1', '5', '7', '12', '19', '32')
    Allerdings hast du bei letzterm natürlich immer nur einen Wert der bei wahrer Bedingung gesetzt werden kann. Einen anderen Weg, mit Hilfe der CASE Anweisung, kenne ich nicht.

    Alternativ kannst du vieleicht einfach 800 Update Befehle durchlaufen, das sollte ähnlich schnell sein.
     
    Walter gefällt das.
  5. michaldo

    michaldo Benutzer

    Ok ich denke ich lasse das einfach in einer Schleife updaten.
     
  6. volvisti

    volvisti Benutzer

    Hallo zusammen,
    ich hab hier einen ähnlichen Fall ...
    Hab mich beim Import der Kategorie-IDs vertan und will nun die Kategorie-ID entsprechend einer Liste ändern ändern.
    Gemäß dem hier von Ukele angegebeben Beispiel hab ich mein Statement (hier gekürzt) folgendermaßen aufgebaut:

    UPDATE `xt_products_to_categories` SET `categories_id`= (case `categories_id` when '3' then '2' when '4' then '14' end)

    Jetzt sagt mir phpMyAdmin bei der Eingabe des Statements

    upload_2016-6-16_11-35-8.png

    Wo liegt mein Fehler, oder liegt es an phpMyAdmin?

    Danke Euch
     
  7. akretschmer

    akretschmer Datenbank-Guru

    in PG geht:

    Code:
    test=# create table volvisti as select * from generate_series(1, 10) s;
    SELECT 10
    test=*# select * from volvisti ;
     s  
    ----
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    (10 Zeilen)
    
    test=*# update volvisti set s = case when s=2 then 22 when s= 5 then 55 else s end;
    UPDATE 10
    test=*# select * from volvisti ;
     s  
    ----
      1
     22
      3
      4
     55
      6
      7
      8
      9
     10
    (10 Zeilen)
    
    test=*#
    
     
  8. ukulele

    ukulele Datenbank-Guru

    Also es gibt zwei Möglichkeiten CASE-Schleifen aufzubauen:
    Code:
    CASE a WHEN b THEN c END
    oder
    Code:
    CASE WHEN a=b THEN c END
    Probier mal die zweite, möglicherweise kennt MySQL oder PHPmyAdmin die erste nicht. Die zweite hat auch den Vorzug das man nicht nur = als Operator verwenden kann sondern auch IN, LIKE, etc., der einzige Nachteil ist die etwas längere Schreibweise da jedesmal a= dort stehen muss.
     
  9. volvisti

    volvisti Benutzer

    Hallo,
    danke Euch für die Hilfe.
    Hab die Meldung einfach mal in einer Testtabelle ignoriet und es hat auch mit den roten Punkten vor der Zeile geklappt.:rolleyes:

    Hat mich zuerst verunsichert. :confused:

    Schönen Tag noch. :)
     
  10. volvisti

    volvisti Benutzer

    zu früh gefreut :(

    Leider liegt auf der Spalte categories_id ein Primärschlüssel und ein Index.
    upload_2016-6-16_13-23-32.png

    Das war in meiner Test-Tabelle natürlich nicht so.

    Geht es dann überhaupt?
    Was kann ich tun?
     
  11. ukulele

    ukulele Datenbank-Guru

    Indexe kann man löschen und neu anlegen.

    Primary Keys kann man auch ändern aber hierbei darf der PK natürlich zu keinem Zeitpunkt doppelt sein. Falls der PK irgendwo als FK dient muss ich dir dringend abraten da MySQL referentielle Intigrität meines Wissens nach nicht durchsetzt. Das wird dann ein Blindflug über die PKs.
     
  12. volvisti

    volvisti Benutzer

    Dann nehme ich einen anderen Weg.
    Löschen und neu importieren :oops:

    Danke Dir
     
Die Seite wird geladen...

Diese Seite empfehlen