recursives WHERE bei UPDATE

ZENeca

Grünschnabel
Server-Typ: MariaDB
Server-Version: 10.5.23-MariaDB-1:10.5.23+maria~ubu2004-log - mariadb.org binary distribution
Protokoll-Version: 10

weiß gar nicht welches ein sinnvoller Titel für diese Frage wäre...
Also, ich glaube nicht daß das machbar ist,
weil sich mal wieder die Katze in den Schwanz beißt
aber ich würde es doch gerne mal klären.
Ich versuche mal das Prinzip zusammen zu fassen

geht um ein UPDATE bei dem sich während des Vorgangs ergibt welche weitere Datensätze betroffen sind

Speziell:
Wenn eine Bedingung zutrifft einen Spaltenwert (update_col) zu ändern
sollen auch alle Spaltenwerte (update_col) geändert werden bei denen
einen anderer Spaltenwert (s_col) dieses Datensatzes auf andere zutrifft


Tabellen-Beispiel
Zeilew_cols_colupdate_col
111up_val
212
323up_val
421up_val
532
633up_val
741up_val
842

UPDATE tab SET update_col = up_val
SELECT s_col FROM tab AS t
WHERE w_col = 2 OR s_col = t.s_col
(funktioniert so natürlich nicht)

sollte dann die Zeilen 1, 3, 4, 6 und 7 betreffen

Also:
die erste WHERE Bedingung betrifft Zeile 3 und 4
dort hat s_col den Wert 3 bzw. 1 und jetzt will ich auch alle
Zeilen ändern bei denen der s_col-Wert auch 3 oder 1 ist
gibt es da irgend ein Lösung?

Wenn es dazu eine Abfrage gäbe wäre das sehr elegant,
sonnst müsste ich das halt auf zwei mal machen.

vielen Dank im Voraus
Zen
 
Zuletzt bearbeitet:
Lösung
Interessante Sache. Das Problem, ich verstehe deine gewünschte Logik noch nicht ganz.
Also. Du gehst mit w_col = 2 an den Start. Daraus liest du die s_col aus. In dem Fall 1 und 3.
Dann sollen alle mit s_col in (1,3) angepasst werden.

Ist eigentlich einfach mit einem Subquery
SQL:
UPDATE my_table
SET update_col = 1234
WHERE s_col IN (
    SELECT s_col
    FROM my_table
    WHERE w_col=2
);
Interessante Sache. Das Problem, ich verstehe deine gewünschte Logik noch nicht ganz.
Also. Du gehst mit w_col = 2 an den Start. Daraus liest du die s_col aus. In dem Fall 1 und 3.
Dann sollen alle mit s_col in (1,3) angepasst werden.

Ist eigentlich einfach mit einem Subquery
SQL:
UPDATE my_table
SET update_col = 1234
WHERE s_col IN (
    SELECT s_col
    FROM my_table
    WHERE w_col=2
);
 
Lösung
Hallo noch mal,

ich weiß nicht, ob es zweckmäßig ist die Frage hier dranzuhängen, aber ich finde das passt gut zum Tread, da es sich eigentlich um eine Ergänzung handelt:

Es geht jetzt um ein UPDATE in beiden Tabellen.
Hab da viel herumprobiert, aber es will einfach nicht funktionieren

SQL:
UPDATE FROM `WARENKORB` AS wk, TRADE_DB AS tdb
LEFT JOIN (SELECT id, End_am, Status FROM tdb) ON tdb.id = wk.tiid
SET wk.reserved = ADDTIME(wk.reserved, TIMEDIFF(NOW(), tdb.End_am)), 
    tdb.Status = tdb.Status & ~138763
WHERE wk.tiid = 1234;

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ON tdb.id = wk.tiid SET wk.reserved = ADDTIME(wk.reserved, TIMEDIFF(NOW(), t...' at line 2

ist das überhaupt möglich oder nur mal wieder ein Denkfehler meinerseits?

LG

Zen
 
Du hast tdb schon in Zeile 1, und machst nen LEFT JOIN auf einen Select von tdb in Zeile 2?

SQL:
UPDATE FROM `WARENKORB` AS wk
LEFT JOIN (SELECT id, End_am, Status FROM TRADE_DB) AS tdb ON tdb.id = wk.tiid
SET wk.reserved = ADDTIME(wk.reserved, TIMEDIFF(NOW(), tdb.End_am)), 
    tdb.Status = tdb.Status & ~138763
WHERE wk.tiid = 1234;

UNGETESTET!
 
Du hast tdb schon in Zeile 1, und machst nen LEFT JOIN auf einen Select von tdb in Zeile 2?

SQL:
UPDATE FROM `WARENKORB` AS wk
LEFT JOIN (SELECT id, End_am, Status FROM TRADE_DB) AS tdb ON tdb.id = wk.tiid
SET wk.reserved = ADDTIME(wk.reserved, TIMEDIFF(NOW(), tdb.End_am)),
    tdb.Status = tdb.Status & ~138763
WHERE wk.tiid = 1234;

UNGETESTET!

mah, sorry, hab die falsche Sequenz kopiert, war nur einer der verzweifelten Versuche,
es sollte eigentlich so lauten:

SQL:
UPDATE FROM `WARENKORB` AS wk, TRADE_DB AS tdb
LEFT JOIN (SELECT id, End_am, Status FROM tdb) ON tdb.id = wk.tiid
SET wk.reserved = ADDTIME(wk.reserved, TIMEDIFF(NOW(), tdb.End_am)),
    tdb.Status = tdb.Status & ~138763
WHERE wk.tiid = 1234;

dein Vorschlag war auch mein erster Versuch und wurde mir Quittiert mit:
Fehler-Nr. 1288 in free_query() - The target table tdb of the UPDATE is not updatable
 
Näxter Versuch
SQL:
UPDATE `WARENKORB` AS wk INNER JOIN TRADE_DB AS tdb
ON (tdb.id = wk.tiid)
SET wk.reserved = ADDTIME(wk.reserved, TIMEDIFF(NOW(), tdb.End_am)),
    tdb.Status = tdb.Status & ~138763
WHERE wk.tiid = 1234;

Ein LEFT JOIN in einem UPDATE, wo du beide Tabellen updaten willst, ist Dummfug
 
Hai Zvoni,
bin die Tage dazugekommen das zu testen und es funktioniert grundsätzlich,
vielen Dank dafür.
Jetzt noch die Frage in welcher Reihenfolge die Updates durchgeführt werden,
mir kommt es vor als würde es die SETs von hinten nach vorne abarbeiten,
aber so lange ich die Reihenfolge nicht explizit vorgeben kann,
wäre mir das zu unsicher und ich würde das doch in zwei Abfragen durchführen
es sei denn es gibt eine Möglichkeit eine Reihenfolge zu garantieren?

lg

Zen
 
Zurück