# Mysql UPDATE if condition



## OnDemand (29. Apr 2020)

Hallo zusammen,

hab grad ein Brett vorm Kopf und bekomme einen Updatequery für folgenden Fall Nicht zusammen:

hab 2 Tabellen

Tabelle A
id
updateable

Tabelle B
id
value

Ich möchte den value in Tabelle B nur updaten, wenn Tabelle a updateable = true ist

Wie kann ich das in einem UPDATE Query realisieren?


----------



## kneitzel (29. Apr 2020)

Da sollte sowas helfen:








						MySQL UPDATE JOIN | Cross-Table Update in MySQL
					

This tutorial shows you how to perform cross-table update by using MySQL UPDATE JOIN statement with INNER JOIN and LEFT JOIN.




					www.mysqltutorial.org
				




Du hast also in dem UPDATE Befehl ein Join auf die zweite Tabelle und änderst dann nur, wenn der Wert entsprechend ist.

Das könnte dann etwas in der Art hinaus laufen:
UPDATE B
JOIN A ON A.id = B.id
SET B.value = newValue
WHERE B.id=someId


----------



## mihe7 (29. Apr 2020)

Kaum fängt man an zu schreiben, kommt schon @JustNobody daher...  

Dann halt Alternativen: 

UPDATE TabelleB SET value = 5 WHERE id IN (SELECT id FROM TabelleA WHERE updateable=true)

UPDATE TabelleB SET value = 5 WHERE EXISTS (SELECT id FROM TabelleA INNER JOIN TabelleB ON TabelleA.id=TabelleB.id WHERE updateable=true)


----------



## OnDemand (29. Apr 2020)

Ah join die hab ich immer gemieden. Ich fürchte ich muss mal kapieren 

Das mit dem Select ist auch cool, gibts performance unterschiede zwischen den Varianten?


----------



## Thallius (29. Apr 2020)

Ein join ist in 90% der Fälle die performantere Lösung. Von Der besseren Lesbarkeit mal ganz abgesehen


----------



## mihe7 (29. Apr 2020)

NicoDeluxe hat gesagt.:


> Das mit dem Select ist auch cool, gibts performance unterschiede zwischen den Varianten?


Das kann man pauschal nicht sagen, da die Anfragen von einem Anfrage-Optimierer optimiert werden


----------



## kneitzel (29. Apr 2020)

mihe7 hat gesagt.:


> UPDATE TabelleB SET value = 5 WHERE EXISTS (SELECT id FROM TabelleA INNER JOIN TabelleB ON TabelleA.id=TabelleB.id WHERE updateable=true)



Das habe ich jetzt nicht ausprobiert, aber da wäre meine Erwartungshaltung, dass er - sobald er in TabelleA einen entsprechenden Eintrag mit id und upateable=true sowie einen Eintrag in B mit der id findet eben alle Datensätze von Tabelle B ändert.
Denn die Bedingung im inneren Select ist entweder erfüllt oder nicht erfüllt - unabhängig von der äußeren UPDATE Anweisung.
Oder habe ich da jetzt einen Denkfehler?Aber ich hätte das INNER JOIN aus dem inneren SELECT heraus genommen und dann halt die id von TabelleB aus der dem äußeren Select genommen... 



NicoDeluxe hat gesagt.:


> Ah join die hab ich immer gemieden. Ich fürchte ich muss mal kapieren
> 
> Das mit dem Select ist auch cool, gibts performance unterschiede zwischen den Varianten?



Das ist so Auf Anhieb nicht zu sagen. Bei MS SQL hätte ich mir einmal den Execution Plan für die Abfragen anzeigen lassen. Erfahrungsgemäß kommt da sehr oft durch die interne Optimierung das Gleiche raus.
Aber bei den inneren Selects kannes zu ganz bösen Effekten kommen, die man eben sonst nicht hat. Das kann ganz böse laufen (Ich hatte da schon ein paar Mal, dass ich Dritten helfen musste, weil ihre Abfragen auf Timeouts liefen und irgenwann war man der Meinung, dass es doof ist, überall höhere Timeouts als Workaround einzubauen und Nutzer Minuten auf Berichte warten zu lassen  )


----------



## kneitzel (29. Apr 2020)

mihe7 hat gesagt.:


> Kaum fängt man an zu schreiben, kommt schon @JustNobody daher...



Das ist übrigens mein "mihe7 antwortet Detektor". Der spinnt aber in letzter Zeit, daher schreibe ich etwas weniger. Es macht halt keinen Spass, wenn man nicht einfach kurz vor Dir antworten kann .... (Ok, böse Zungen behaupten, dass ich derzeit Urlaub habe und da andere Prioritäten habe ... Aber das sind natürlich reine Verschwörungstheorien - auf einer Stufe mit "Bielefeld existiert", "Die Erde ist rund" und "Trump ist kein Außerirdischer".)


----------



## mihe7 (29. Apr 2020)

JustNobody hat gesagt.:


> Das habe ich jetzt nicht ausprobiert, aber da wäre meine Erwartungshaltung, dass er - sobald er in TabelleA einen entsprechenden Eintrag mit id und upateable=true sowie einen Eintrag in B mit der id findet eben alle Datensätze von Tabelle B ändert.


Örks, Du mit Deinem JOIN hast mich ganz verwirrt  

So war das gemeint:

UPDATE TabelleB SET value = 5 WHERE EXISTS (SELECT id FROM TabelleA WHERE TabelleA.id=TabelleB.id AND updateable=true)


----------



## mihe7 (29. Apr 2020)

JustNobody hat gesagt.:


> Das ist übrigens mein "mihe7 antwortet Detektor".


Ich sags ja: https://www.java-forum.org/thema/was-ist-mit-meinem-account-passiert.188122/#post-1218734


----------



## kneitzel (29. Apr 2020)

mihe7 hat gesagt.:


> Örks, Du mit Deinem JOIN hast mich ganz verwirrt
> 
> So war das gemeint:
> 
> UPDATE TabelleB SET value = 5 WHERE EXISTS (SELECT id FROM TabelleA WHERE TabelleA.id=TabelleB.id AND updateable=true)



Ja, so halte ich es auf den ersten Blick auch für korrekt.



Thallius hat gesagt.:


> Ein join ist in 90% der Fälle die performantere Lösung. Von Der besseren Lesbarkeit mal ganz abgesehen


Dem stimme ich aber auch noch zu, auch wenn es Fälle gibt, in denen die Performance gleich ist.

Kleiner Exkurs - viel persönliche Sicht und der werden einige nicht zustimmen:
Bei den Queries würde ich dies bei MS SQL erwarten, mysql ist aber halt in meinen Augen keine ernst zu nehmende Datenbank - aber das liegt einfach nur daran, dass mein Kontakt zu mysql zu einer Zeit war, in der keine foreign keys unterstützt wurden so die Tabellen im bevorzugten Datenbank-Format geschrieben wurden... Relationale Datenbank ohne Foreign Keys? Das prägt ganz schön  ... Aber klar: das war damals, heute ist mysql besser. Ich habe es selbst "produktiv" im Einsatz bei einem Kunden, aber die Backups in Form von SQL Scripten mit den teilweise damit verbundenen Problemen bezüglich Collation? So gewisse Dinge kann ich immer noch nicht so ganz nachvollziehen und "enterprise level" ist bei mir doch etwas anderes ... zumal da oracle hinter steckt ... Da sinken die Erwartungshaltungen gleich massiv ... die einzige Erwartung, die da immer erfüllt wird: Man wird garantiert sein Geld los


----------



## mihe7 (29. Apr 2020)

JustNobody hat gesagt.:


> Da sinken die Erwartungshaltungen gleich massiv ...


LOL. So ist das. 

mysql ist halt "historisch bedingt" die Datenbank fürs Web. Ich frage mich, warum PostgreSQL nicht stärker verbreitet ist, oder ist das mittlerweile anders?


----------



## kneitzel (29. Apr 2020)

mihe7 hat gesagt.:


> mysql ist halt "historisch bedingt" die Datenbank fürs Web. Ich frage mich, warum PostgreSQL nicht stärker verbreitet ist, oder ist das mittlerweile anders?



Also in meinem Bekanntenkreis ist das die bevorzugte Wahl. Aber irgendwie hat sich mysql massiv im markt durchgesetzt. Unverständlich. zumal das am Anfang ja kaum etwas bot. Aber das war vielleicht das reizvolle für Anfänger: Super - da muss man viel weniger lernen. Bei PostgreSQL erzählen die "Profis" einem immer Dinge, die man machen müsste für Dinge, die man nicht kennt und auch gar nicht will ... ein Integriertes Referat ... referiertes Integral? Ein Integren Referenten? Siehst Du: Ich komme noch nicht einmal mehr auf den Begriff "referentielle Integrität" und wenn man den Begriff nicht merken kann, dann kann es nur unwichtig sein ...


----------



## mihe7 (29. Apr 2020)

JustNobody hat gesagt.:


> komme noch nicht einmal mehr auf den Begriff "referentielle Integrität" und wenn man den Begriff nicht merken kann, dann kann es nur unwichtig sein ...


Hört sich eher nach Access an


----------



## kneitzel (29. Apr 2020)

mihe7 hat gesagt.:


> Hört sich eher nach Access an


Ach, das ist doch super. Access ist geil. Du brauchst gar keine Datenbank Kenntnisse! Du klickst dir einfach Tabellen zusammen, verbindest die u.s.w.
Dann baust Abfragen (vergleichbar mit View) ... fängst klein an ... und dann baust du Abfragen auf Abfragen  ... Alles super!

Und dann packst Du das einfach auf einen SQL Server. Oder Du hast es schon immer mit SQL Backend entwickelt. Total genial!

Und wie man Timeouts so einstellt, das eine Abfrage auf eine View auch über Nacht laufen kann, das ist dann ein Spezialwissen, das man bei sowas dann auch schnell bekommt.

Vor allem unbezahlbar: Man sagt DB Admins, das sie gewisse Timeouts einstellen sollen ... Der Moment, in dem die Admins verstehen, was da verlangt wird, ist unbezahlbar.

Und für IT Dienstleister ist das top: So kriegt man schnell noch einen zweiten Datenbank Cluster. 
Darf halt nur nie ein Kunde auf die Cluster schauen


----------

