Rolf b: SQL Frage zu update

Beitrag lesen

Dedlfixens Konstrukt enthält mehrere Dinge, die Du möglicherweise nicht kennst.

(1) UNION. Das ist ein SQL Sprachkonstrukt, das die Ergebnismengen mehrerer SELECTs zu einer Ergebnismenge zusammenfasst. Funktioniert natürlich nur, wenn die SELECTS so sind, dass das machbar ist (gleiche Spaltenzahl, gleiche oder zumindest konvertierbare Datentypen). Gleiche SpaltenNAMEN müssen es übrigens nicht unbedingt sein, SQL verwendet bei Widersprüchen die Namen des ersten SELECT (gilt für MS SQL Server, ob das auch bei MySQL so ist, weiß ich nicht).

UNION macht noch etwas mehr als nur Zeilen aneinander zu kängen. Er bildet eine echte Vereinigungsmenge, d.h. er entfernt Duplikate, was bei großen Datenmengen durchaus Zeit kosten kann. Will man diesen Schritt vermeiden, schreibt man statt "UNION" ein "UNION ALL".

(2) Konstanten in der SELECT Liste. Dafür gibt es unterschiedliche Anlässe. Einer ist, wenn man ein UNION-Konstrukt hat und den Ergebnissätzen ihre Herkunft ansehen können will. Das passiert hier.

(3) Alias-Namen für Ergebnisspalten. Verwendet man, um bei Angabe von Konstanten für eine Spalte einen definierten Spaltennamen zu haben, oder um Spalten für die Ergebnismenge umzubenennen. Normalerweise wird ein Alias mit AS definiert, also aID as ID, das AS ist aber optional.

Du kannst dein Update nun so schreiben, ganz ausführlich:

UPDATE b
SET Lob = (SELECT Lob
           FROM (SELECT 'a' part, aId ID, Lob FROM a
                 UNION
                 SELECT 'f' part, fId ID, Lob FROM f
                 UNION
                 SELECT 't' part, tId ID, Lob FROM t) aft
           WHERE aft.part = b.part AND aft.ID = b.ID)

D.h. du klebst die drei Teil-Queries erstmal zusammen, um dann per WHERE einen einzigen Satz davon herauszufieseln. Das ist eine Herausforderung für den Optimizer im SQL Server, darum habe ich dieses Statement rot angepinselt.

Man kann VIEWs aber auch als Datenbankobjekte erzeugen - hier in der einfachsten Form. Die ekligen Details findest Du hier.

CREATE VIEW aft AS
   SELECT 'a' part, aId ID, Lob FROM a
   UNION
   SELECT 'f' part, fId ID, Lob FROM f
   UNION
   SELECT 't' part, tId ID, Lob FROM t

Mit diesem View wird das Updatemonster von oben zu

UPDATE b
SET Lob = (SELECT Lob FROM aft WHERE aft.part = b.part AND aft.ID = b.ID)

Sieht trügerische simpel aus, ist aber für den SQL Optimizer genauso problematisch wie das Monster. Die Ergebnismenge eines VIEW wird nicht gespeichert. Du kannst den VIEW hier wie einen Textbaustein betrachten, der in eine Query eingefügt wird. Ok ok, das war eine "Lüge für Kinder" - hinter Views steckt mehr als das...

D.h. als "grün", oder empfehlenswert, würde ich für deine Aufgabenstellung die Lösung mit den 3 Updates ansehen.

Rolf