MYSQL: Update mit werten aus anderer Tabelle


Opor

Grünschnabel
MYSQL 4.0.16: Update mit werten aus anderer Tabelle

Hallo,

ich habe folgendes Problem:
Ich habe 2 Tabellen:
-> User und Order
In der Tabelle User sind alle Nutzer gespeichert.
In der Tabelle Bestellungen sind beliebig viele die Bestellung verschiedener Nutzer. Es kann aber auch ein Nutzer mehrere Bestellungen haben.
In der Tabelle User existiert eine Uid welche auch in der Tabelle Bestellung logischerweise existiert.

Ich möchte nun per UPDATE den Wert createDate in der Tabelle User ändern.
Der Wert in den geändert wird stammt aus der Tabelle Bestellungen. Er ist das kleinste Datum aus der Tabelle Bestellungen.

Ich habe schon einiges ausprobiert, doch leider bin ich immernoch nicht zu einem Ergebnis gekommen.
Es handelt sich um eine MYSQL Datenbank!

So ungefähr sollte es aussehen:
UPDATE user,order SET user.createDate = Min( order.orderDate ) WHERE user.Uid = order.Uid

Vielen Dank für eure Hilfe
 
Zuletzt bearbeitet:

ManicMarble

Erfahrenes Mitglied
Hallo Opor,

zunächst mal: Updates über mehrere Tabellen sind grundsätzlich "tricky" (siehe dazu die MySQL-Doku, speziell die Kommentare).

Dann: Der Tabellen-Name "order" ist nicht sehr empfehlenswert, da der Interpreter diesen Namen gerne mit dem ORDER BY verwechselt, ergo muss der Tabellenname order immer als `order` geschrieben werden, sonst droht Syntax-Error.

Ein weiteres Problem ist die Gruppen-Funktion MIN() ohne GROUP BY.

So, jetzt 2 Lösungsvorschläge, einmal mit SubQuery (ab MySQL 4.1):
Code:
UPDATE
 user AS u
LEFT JOIN
 (SELECT uid, MIN(datum) AS mindatum FROM `order` GROUP BY uid) AS o ON u.id = o.uid
SET
 u.createDate = o.mindatum
und einmal mit temporärer Tabelle (MySQL 4.0 und früher):
Code:
DROP TABLE IF EXISTS tmp_order;

CREATE TEMPORARY TABLE tmp_order TYPE = HEAP
 SELECT uid, MIN(datum) AS mindatum FROM `order` GROUP BY uid;

UPDATE
 user
LEFT JOIN
 tmp_order ON user.id = tmp_order.uid
SET
 user.createDate = tmp_order.mindatum;

DROP TABLE IF EXISTS tmp_order;
Vielleicht hilft's.
Grüße,
Martin
 
S

steph

Hallo,

vielen Dank für diese Antwort - die hat mir auch sehr weitergeholfen.
Vorher habe ich immer nur dumme Kommentare und Verweise auf die Handbücher gefunden, in denen ein Beispiel dieser Art aber nicht enthalten ist.

VIELEN DANK nochmals :)

grüße
steph.
 

Mc_Fly_B

Mitglied
Hallo,

habe auch ein ähnliches Problem. Ähnlich in dem Sinne, dass zusätzlich ein weiterer Wert in selbiger Tabelle von einer anderen Tabelle referenziert wird... kompliziert genug?!

Folgende Tabellen:
Beiträge (id_beitrag, id_thema, titel) t1
Themen (id_thema, id_erster_beitrag) t2

Beispielinhalte:
t1
1, 1, Irgendwas
2, 1,
3, 2, Nochwas
4, 3, Wieder was
5, 1,
6, 3,
usw.

t2
1, 1
2, 3
3, 4
usw.

Überall dort, wo auf Beiträge geantwortet wurde, stehen keine Titel drin. Dort soll aber der Titel jetzt geändert werden auf: "Antwort auf: " und dann der Titel des ersten Beitrags.
Also wenn t1.id_beitrag = t2.id_erster_beitrag bleibt titel oder noch besser anders herum: wenn t1.id_beitrag <> t2.id_erster_beitrag wird titel = "Antwort auf: ",(titel, wo id_beitrag = id_erster_beitrag ist)

Die erste Tabelle sollte danach so aussehen:
1, 1, Irgendwas
2, 1, Antwort auf: Irgendwas
3, 2, Noch was
4, 3, Wieder was
5, 1, Antwort auf: Irgendwas
6, 3, Antwort auf: Wieder was
usw.

Komme auch mit obigen Beispielen leider nicht weiter.

Mc Fly
 

Yaslaw

n/a
Moderator
Auf die Schnelle gezimmert und nicht getestet könnte es ev. etwa so gehen.

SQL:
SELECT
	antw.id_thema,
	antw.id_beitrag,
	CONCAT("Auntwort auf: ", erste.title) AS title
FROM
	(SELECT t1.id_beitrag, t1.id_thema
	FROM t1
	WHERE (t1.id_thema, t1.id_beitrag) NOT IN (SELECT t2.id_thema, t2.id_beitrag FROM t2)) AS antw,
	(SELECT t1.id_thema, t1.title
	FROM t1		
	WHERE (t1.id_thema, t1.id_beitrag) NOT IN (SELECT t2.id_thema, t2.id_beitrag FROM t2)) AS erste
WHERE
	antw.id_thema = erste.id_thema
UNION SELECT 
	t1.id_thema, 
	t1.id_beitrag,
	t1.title
FROM t1		
WHERE (t1.id_thema, t1.id_beitrag) NOT IN (SELECT t2.id_thema, t2.id_beitrag FROM t2)) AS erste
 
Zuletzt bearbeitet von einem Moderator:

Mc_Fly_B

Mitglied
Auf die Schnelle übernommen und getestet ergab sich folgender Fehler:

#1064 ... syntax to use near ') AS erste LIMIT 0, 30' at line 19

Und wo t2.id_beitrag steht ist t2.id_erster_beitrag gemeint? Gehe ich mal von aus.

Mc Fly
 

Yaslaw

n/a
Moderator
Hab am ende von C&P ein ') AS erste' zu viel (letzte Zeile)
Und ja, t2.id_erster_beitrag - natürlich
 

Mc_Fly_B

Mitglied
Nachdem ich noch Beiträge AS t1 und Themen AS t2 überall eingetragen hatte, lief es.

Brachte allerdings für title überall nur "Antwort auf: " und sonst nix, dafür aber auch gleich in doppelter Anzahl der zu behebenden Zeilen... :( Genauer nachgeschaut: erste Hälfte des Ergebnisses "Antwort auf: ", zweite Hälfte ist title leer.
Die Abfrage nimmt sich also nicht den Titel aus dem ersten Beitrag, sondern den aus dem aktuellen.

Was mir gerade auffällt (soweit meine Logik am Morgen schon funktioniert... ;) ):
Tut's für die letzte, also äußere, Bedingung nicht auch ein simples:
SQL:
WHERE t1.id_beitrag <> t2.id_erster_beitrag
Das Teil dauert nämlich reichlich lange...

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:

Mc_Fly_B

Mitglied
Also die beiden Abfragen um die Einzelergebnisse zu erhalten:

t1.id_beitrag mit leerem titel
SQL:
SELECT t1.id_beitrag
FROM beitraege AS t1 , themen AS t2
WHERE t1.id_beitrag <> t2.id_erster_beitrag AND t1.id_thema = t2.id_thema;

titel von t2.id_thema
SQL:
SELECT t1.titel
FROM beitraege AS t1 , themen AS t2
WHERE t1.id_beitrag = t2.id_erster_beitrag

Das muss doch recht simpel zu verknüpfen sein?!

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:

Neue Beiträge

Forum-Statistiken

Themen
272.361
Beiträge
1.558.639
Mitglieder
187.834
Neuestes Mitglied
jordanx0206