Update-Select Verschachtelung

ruehau

Neuer Benutzer
Beiträge
3
Hallo Leute,

ich stehe vor einem Problem, für das ich einfach keine Lösung finden kann..

Meine Tabelle sieht folgendermaßen aus:

PrimaryKey1 | PrimaryKey2 | Wert1 | Wert2 | Wert3

Wenn das Feld Wert1 nun einen bestimmten Wert hat, so möchte ich die Werte1, 2 und 3 überall dort setzten, wo der PrimaryKey1 gleich ist..

oder um es vielleicht etwas klarer auszudrücken..

SELECT PrimaryKey1 AS PrimaryKey1AusSelect, Wert1 AS Wert1AusSelect, Wert2 AS Wert2AusSelect, Wert3 AS Wert3AusSelect FROM tabelle WHERE Wert1 = 5
für jede gefundene Zeile: UPDATE tabelle SET Wert1 = Wert1AusSelect, Wert2 = Wert2AusSelect, Wert3 = Wert3AusSelect WHERE PrimaryKey1 = PrimaryKey1AusSelect

-- nun möchte ich die obigen Anweisung in eine einzige SQL-Abfrage zusammen packen.. gibt es da eine Möglichkeit oder möchte ich vielleicht zu viel?
 
Werbung:
Zuerst einmal: du kannst nicht 2 primary Keys haben. Es kann nur einen geben.

So ganz versteh ich Dein Problem aber nicht, kannst Du es an einem Beispiel zeigen? Du kannst im Update auch ein Where angeben, vermutlich löst das schon Dein Problem.
 
Hallo,

es handelt sich um einen Primary, der sich über 2 Felder erstreckt.

Als Beispiel:

PrimaryKey1, PrimaryKey2, Wert1, Wert2, Wert3
1, 1, 0, 0, 0
1, 2, 0, 0, 0
2, 1, 5, 2, 1 <- wenn Wert1 = 5
2, 2, 0, 0, 0
2, 3, 0, 0, 0
3, 1, 0, 0, 0
3, 2, 0, 0, 0

Nach der Anweisung soll die Tabelle folgendermaßen aussehen:

1, 1, 0, 0, 0
1, 2, 0, 0, 0
2, 1, 5, 2, 1
2, 2, 5, 2, 1 <- dann Werte überall setzen wo Primary1 gleich ist
2, 3, 5, 2, 1 <-
3, 1, 0, 0, 0
3, 2, 0, 0, 0

Hoffe, das ist noch etwas anschaulicher..
 
Geht so:

Code:
test=# select * from ruehau ;
 p1 | p2 | w1 | w2 | w3
----+----+----+----+----
  1 |  1 |  0 |  0 |  0
  1 |  2 |  0 |  0 |  0
  2 |  1 |  5 |  2 |  1
  2 |  2 |  0 |  0 |  0
  2 |  3 |  0 |  0 |  0
  3 |  2 |  0 |  0 |  0
(6 rows)

test=*# with tmp as (select p1,p2,w1,w2,w3 from ruehau where w3=1) update ruehau r set w1=tmp.w1, w2=tmp.p2, w3=tmp.w3 from tmp where (r.p1) = (tmp.p1);
UPDATE 3
test=*# select * from ruehau ;
 p1 | p2 | w1 | w2 | w3
----+----+----+----+----
  1 |  1 |  0 |  0 |  0
  1 |  2 |  0 |  0 |  0
  3 |  2 |  0 |  0 |  0
  2 |  1 |  5 |  1 |  1
  2 |  2 |  5 |  1 |  1
  2 |  3 |  5 |  1 |  1
(6 rows)

Allerdings NICHT in MySQL. Da wirst wohl das über die Applikation regeln müssen.
 
Hallo akretschmer,

die Logik klingt gut, aber wie du schon geschrieben hast, bekomme ich die in mySql bzw. mariaDB nicht umgesetzt.
Wo bist du unterwegs.. Oracle bzw Postgre vermute ich mal?

Falls noch jemand eine Hilfestellung hat, wie ich mein Problem in mySQL umsetzten kann, wäre ich sehr dankbar. Ansonsten muss ich leider dann den Schritt über die Applikation machen und mir alles einzeln heraus sortieren..
 
Was machst du denn bei folgenden Datensätzen:
2, 1, 5, 2, 1 <- Wert1 = 5
2, 2, 0, 0, 0
2, 3, 5, 3, 2 <- Wert1 = 5
ist das Ergebnis dann:
2, 1, 5, 2, 1
2, 2, 5, 2, 1
2, 3, 5, 2, 1
oder:
2, 1, 5, 3, 2
2, 2, 5, 3, 2
2, 3, 5, 3, 2
 
Ich würde es unter MSSQL so lösen:
Code:
UPDATE   tabelle
SET     tabelle.wert1 = t.wert1,
     tabelle.wert2 = t.wert2,
     tabelle.wert3 = t.wert3
FROM   tabelle
INNER JOIN tabelle t
ON     tabelle.pk1 = t.pk1
AND     tabelle.pk2 != t.pk2
AND     t.wert1 = 5
Da wird MySQL aber möglicherweise wegen self referencing tabeles meckern oder so.
 
Werbung:
Das geht möglicherweise nicht in Oracle, oder?
Nicht in der selben Syntax, da Joins beim Update nicht erlaubt sind...
Generell benutzt man für Multi-Table Updates eher Merge... Es ist aber auch mit einem Update möglich

Code:
SQL> Create Table fps_max_test_tab(id Number(3, 0), val Varchar2(100), Constraint fps_max_test_pk Primary Key (id));
Table created

SQL> Insert Into fps_max_test_tab (id, val) Values (1, 'A');
1 row inserted

SQL> Insert Into fps_max_test_tab (id, val) Values (2, 'B');
1 row inserted

SQL> Insert Into fps_max_test_tab (id, val) Values (3, 'C');
1 row inserted

SQL> Commit;
Commit complete

SQL> Select * From fps_max_test_tab;
  ID VAL
---- --------------------------------------------------------------------------------
   1 A
   2 B
   3 C

SQL> -- Methode wie man es eigentlich macht
SQL> Merge Into fps_max_test_tab t
  2  Using (Select Min(id) As min_id
  3         From fps_max_test_tab) p
  4  On    (t.id = p.min_id)
  5  When  Matched Then
  6    Update
  7      Set t.val = 'Z';
1 row merged

SQL> Commit;
Commit complete

SQL> Select * From fps_max_test_tab;
  ID VAL
---- --------------------------------------------------------------------------------
   1 Z
   2 B
   3 C

SQL> -- Methode mit CTE
SQL> Merge Into fps_max_test_tab t
  2  Using (With dat As (Select Max(id) As max_id
  3                      From   fps_max_test_tab)
  4         Select * From dat) p
  5  On    (t.id = p.max_id)
  6  When  Matched Then
  7    Update
  8      Set t.val = 'Y';
1 row merged

SQL> Commit;
Commit complete

SQL> Select * From fps_max_test_tab;
  ID VAL
---- --------------------------------------------------------------------------------
   1 Z
   2 B
   3 Y

SQL> -- Spielerei mit Update
SQL> Update fps_max_test_tab t Set t.val = 'X' Where t.id = (With dat As (Select Avg(id) As avg_id From fps_max_test_tab) Select avg_id From dat);
1 row updated

SQL> Select * From fps_max_test_tab;
  ID VAL
---- --------------------------------------------------------------------------------
  1 Z
  2 X
  3 Y

SQL>
 
Zurück
Oben