Linuchs: UPDATE abhängig von anderen Tabellen

Moin,

mit phpmyadmin möchte ich in einem fünfstelligen Feld ein X auf Stelle 5 setzen, wenn zu diesem Datensatz in zwei anderen Tabellen keine Einträge vorliegen:

UPDATE    tm_adressen adr1
LEFT JOIN tm_kontakte kon1
ON        kon1.besucher_id  = adr1.id
LEFT JOIN tm_eventbuchungen evb1
ON        evb1.adress_id    = adr1.id
SET       adr1.merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), 'X' )
WHERE adr1.owner_id  = 15
AND   adr1.adr_kz    = 2
AND   kon1.id IS NULL
AND   evb1.id IS NULL

Meldung: 0 Zeile(n) betroffen. ( die Abfrage dauerte 0.0039 sek. )

Aber das X wurde bei allen Adressen gesetzt.

Was ist an dem SQL-Kommando falsch?

Linuchs

  1. Sorry, ich habe Randbedingungen vergessen. Aber bei manchen vorhandenen Kontakten (nicht bei allen) wird ein X gesetzt, bei manchen fehlenden Kontakten (aber nicht bei allen) fehlt das X. Irgendwie scheint da jemand zu würfeln:

    # . auf Stelle 5 setzen (X zuruecknehmen)
    UPDATE tm_adressen
    SET merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), '.' )
    WHERE owner_id  = 15
    AND   adr_kz    = 2;
    
    # X auf Stelle 5, wenn keine Kontakt- und keine Eventwuensche
    UPDATE    tm_adressen adr1
    LEFT JOIN tm_kontakte kon1
    ON        kon1.besucher_id  = adr1.id
    AND       kon1.prio_1       = 0
    AND       kon1.prio_2       = 0
    #LEFT JOIN tm_eventbuchungen evb1
    #ON        evb1.adress_id    = adr1.id
    #AND       evb1.prio_1       = 0
    #AND       evb1.prio_2       = 0
    SET       adr1.merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), 'X' )
    WHERE adr1.owner_id  = 15
    AND   adr1.adr_kz    = 2
    AND   kon1.id IS NULL
    #AND   evb1.id IS NULL;
    

    Linuchs

  2. Hi,

    mit phpmyadmin möchte ich in einem fünfstelligen Feld ein X auf Stelle 5 setzen, wenn zu diesem Datensatz in zwei anderen Tabellen keine Einträge vorliegen:

    Das deutet darauf hin, daß das eigentlich eher fünf einstellige Felder sein sollten ...

    UPDATE    tm_adressen adr1
    LEFT JOIN tm_kontakte kon1
    ON        kon1.besucher_id  = adr1.id
    LEFT JOIN tm_eventbuchungen evb1
    ON        evb1.adress_id    = adr1.id
    SET       adr1.merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), 'X' )
    WHERE adr1.owner_id  = 15
    AND   adr1.adr_kz    = 2
    AND   kon1.id IS NULL
    AND   evb1.id IS NULL
    

    join beim Update? Ist das überhaupt erlaubt?

    Ich hätte das eher so gelöst:

    
    UPDATE tm_adressen adr1
    SET adr1.merkmalWederKontaktNochEvent = 1
    WHERE adr1.owner_id = 15
    AND NOT EXISTS (SELECT id FROM tm_kontakte kon1 WHERE kon1.besucher_id = adr1.id) 
    AND NOT EXISTS (SELECT id FROM tm_eventbuchungen evb1 WHERE evb1.adress_id = adr1.id)
    AND adr1.adr_kz = 2
    
    

    cu,
    Andreas a/k/a MudGuard

    1. Hallo MudGuard,

      join beim Update? Ist das überhaupt erlaubt?

      Nö.

      Ich hätte das eher so gelöst: […]

      Ich wohl auch.

      LG,
      CK

      1. Tach,

        join beim Update? Ist das überhaupt erlaubt?

        Nö.

        in MySQL schon (in Postgres nicht und ich habe keine Ahnung, ob das aus einem SQL-Standard ist): „You can also perform UPDATE operations covering multiple tables. However, you cannot use ORDER BY or LIMIT with a multiple-table UPDATE. The table_references clause lists the tables involved in the join. Its syntax is described in Section 14.2.9.2, “JOIN Syntax”.“ - http://dev.mysql.com/doc/refman/5.7/en/update.html

        Ich hätte das eher so gelöst: […]

        Ich wohl auch.

        dito

        mfg
        Woodfighter

    2. Hallo Andreas,

      sorry, dass ich erst heute dazu komme, deinen Vorschlag umzusetzen. Er ist perfekt. danke.

      Das deutet darauf hin, daß das eigentlich eher fünf einstellige Felder sein sollten ...

      Habe mich bewusst für ein multiple-choice-field entschieden. Die Eingabe in <form> ist kompakter und die Zahl der Möglichkeiten (varchar (nn) in verschiedenen Projekten) ist variabel.

      Ich hätte das eher so gelöst:

      UPDATE tm_adressen adr1
      SET adr1.merkmalWederKontaktNochEvent = 1
      WHERE adr1.owner_id = 15
      AND NOT EXISTS (SELECT id FROM tm_kontakte kon1 WHERE kon1.besucher_id = adr1.id) 
      AND NOT EXISTS (SELECT id FROM tm_eventbuchungen evb1 WHERE evb1.adress_id = adr1.id)
      AND adr1.adr_kz = 2
      

      Linuchs

      1. Tach,

        Das deutet darauf hin, daß das eigentlich eher fünf einstellige Felder sein sollten ...

        Habe mich bewusst für ein multiple-choice-field entschieden.

        als Eingabeformat mag das ja u.U. vorteilhaft sein, aber als Speicherformat ist es eher verstörend.

        mfg
        Woodfighter

      2. Hi,

        Habe mich bewusst für ein multiple-choice-field entschieden. Die Eingabe in <form> ist kompakter und die Zahl der Möglichkeiten (varchar (nn) in verschiedenen Projekten) ist variabel.

        Die Darstellung der gespeicherten Werte sowie die Eingabe ist doch unabhängig vom Speicherformat. Ob Du für eine Multiple-Choice-Eingabe die Werte für die einzelnen Checkboxes aus EINEM String mit N Zeichen extrahierst oder aus N Spalten, spielt keine wirkliche Rolle. Genauso beim Schreiben der Daten.

        Wobei hier ja nicht mal eine Eingabe vom User getätigt wird, da sich das X ja aus anderweitig vorhandenen (bzw. eben gerade nicht vorhandenen) Daten ergibt, also eigentlich redundant ist - aus Performance-Gründen kann es aber durchaus gerechtfertigt sein, so eine redundante Information trotzdem abzuspeichern - halt immer mit der Gefahr verbunden, daß die redundante Information nicht angepaßt wird, wenn sich deren Datengrundlage ändert.

        cu,
        Andreas a/k/a MudGuard

  3. Tach!

    mit phpmyadmin möchte ich in einem fünfstelligen Feld ein X auf Stelle 5 setzen, wenn zu diesem Datensatz in zwei anderen Tabellen keine Einträge vorliegen:

    [...]

    Was ist an dem SQL-Kommando falsch?

    Weiß ich grad nicht und möchte das jetzt auch nicht ergründen. Aber bring mal die Joins auf einen hinteren Platz in deinem SQL-Lösungsrepertoire und schau dir Subquerys an, besonders diejenigen mit EXISTS oder NO EXISTS und sicherlich brauchst du auch noch Korrelationen. Du kannst in der Subquerys zunächst mal die Nebenbedingung ausformulieren und diese separat testen, ob sie die gewünschte Ergebnismenge liefern. Danach kannst du sie in die Hauptquery einbauen, die ihrerseits ebenfalls vorher separat getestet werden kann. Wenn du hingegen Joins zu verwenden versuchst, hast du nur einen großen Haufen und kannst die Lösungsfindung nicht oder nur schlecht auf kleinere Einheiten herunterbrechen.

    dedlfix.