aktualisieren einer Tabelle mit Wert aus einer anderen

Thomas220

Benutzer
Beiträge
17
Hallo zusammen, habe hier zwei Tabellen. T1 und T2.
In T1 steht ein Feld "Nummer" und ein Feld "Name". Das Feld "Name" ist noch leer. Im Feld "Nummer" stehen Zahlen.
In T2 gibt es drei Felder "vonNr", "bisNR" und "Name".

Nun möchte ich den Wert von T2-"Name" in T1-"Name" schreiben, wenn T1-"Nummer" >= T2-"vonNR" UND <= T2-"bisNR" ist. Dabei gilt, dass T1-"Nummer" nur genau einem Bereich aus T2-"vonNr" und T2-"bisNR" zugeordnet werden kann.

In MSSQL hatte ich die Abfrage so gestaltet:
Code:
update T1 set T1.Name=n.Name
from T1 as b
inner join T2 as n
on b.Nummer >= n.vonNR and b.Nummer <= n.bisNR

In MySQL geht das sooo wohl nicht.
Aber wie geht es.

Vielen Dank für Hilfe.

Thomas
 
Werbung:
Hallo akretschmer, danke für Dein Interesse.
Fehlermeldung ist defizil: Stört sich schon an dem Wort bzw. der Zeile, die mit"from" beginnt.

Bei der Erstellung der T2 wird peinlich darauf geachtet, dass es zu keinen Überlappungen oder Dopplungen kommt. Daher meine Gewissheit ;-)

Eine Idee, wie man das mit MySQL hinbekommt.

Thomas
 
Hallo akretschmer, hier habe ich ein neues Statement gebastelt, welches nun aber die folgende Fehlermeldung erzeugt.
Code:
update T1, T2 set T1.Name=T2.Name
where T1.Nummer >= T2.vonNR and T1.Nummer <= T2.bisNR
Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.

Thomas
 
Also ich hätte das ähnlich versucht wie bei deinem ersten Statement, eventuell stört sich MySQL an dem Alias von T1, probier mal:
Code:
UPDATE T1
SET T1.Name = n.Name
FROM T1
INNER JOIN T2 AS n
ON T1.Nummer BETWEEN n.vonNR AND n.bisNR
Der "safe mode" kann natürlich nach wie vor ein Problem sein, das hätte dir aber G**gle auch gesagt:
MySQL Workbench – Safe Updates Deaktivieren
 
Code:
test=*# select * from t1;
 nummer | name
--------+------
  5 |
  15 |
  25 |
(3 Zeilen)

test=*# select * from t2;
 von | bis |  name   
-----+-----+---------
  1 |  10 | Andreas
  11 |  20 | Max
  21 |  30 | Hans
(3 Zeilen)

test=*# update t1 set name=t2.name from t2 where t1.nummer between t2.von and t2.bis;
UPDATE 3
test=*# select * from t1;
 nummer |  name   
--------+---------
  5 | Andreas
  15 | Max
  25 | Hans
(3 Zeilen)

test=*#

geht so in PostgreSQL. Um überlappende Bereiche in T2 zu vermeiden, also sowas wie:

Code:
test=*# insert into t2 values (2,9,'Knallfrosch');
INSERT 0 1
test=*# select * from t2;
 von | bis |  name   
-----+-----+-------------
  1 |  10 | Andreas
  11 |  20 | Max
  21 |  30 | Hans
  2 |  9 | Knallfrosch
(4 Zeilen)

könnte man (natürlich nur mit PostgreSQL) sowas machen:

Code:
test=*# create table t2_new(nummer int4range, name text, exclude using gist(nummer with &&));
CREATE TABLE
test=*# insert into t2_new values ('[1,10)','Andreas');
INSERT 0 1
test=*# insert into t2_new values ('[11,20)','Max');
INSERT 0 1
test=*# insert into t2_new values ('[21,30)','Hans');
INSERT 0 1

Das Update wäre dann:

Code:
test=*# update t1 set name = t2_new.name from t2_new where t2_new.nummer @> t1.nummer;
UPDATE 3
test=*# select * from t1;
 nummer |  name   
--------+---------
  5 | Andreas
  15 | Max
  25 | Hans
(3 Zeilen)

Und der Knallfrosch hätte keine Chance:

Code:
test=*# insert into t2_new values ('[2,9)','Knallfrosch');
FEHLER:  kollidierender Schlüsselwert verletzt Exclusion-Constraint »t2_new_nummer_excl«
DETAIL:  Schlüssel (nummer)=([2,9)) kollidiert mit vorhandenem Schlüssel (nummer)=([1,10)).
 
Hallo zusammen, so wie das Ukulele schrieb habe ich das auch probiert. Geht auch nicht. Stört sich wieder an der Zeile "from".
Habe jetzt eine Lösung gefunden, die zwar funktioniert, aber seeeeehr lange dauert.
Code:
update T1, T2 set T1.Name=T2.Name
where t1.Nummer >= T2.vonNR and T1.Nummer <= T2.bisNR

Tabelle T1 hat rund 60.000 Datensätze, T2 rund 46.000 Datensätze. Da nicht alle Nummern aus T1 in T" vorkommen, werden "lediglich" 1.275 Datensätze zu aktualisieren. Dauert etwa 1 Stunde (3.157 sec.).

Würde es helfen das >= und<= durch "between" zu ersetzen. Nur mal testen is ja nicht so schnell erledigt :-(

Danke.
Thomas
 
Werbung:
Vielleicht geht:
Code:
UPDATE T1
SET Name = (
SELECT n.Name
FROM T2 n
WHERE T1.Nummer BETWEEN n.vonNR AND n.bisNR )
Performancetechnisch ist das auch nicht geil aber 1h ist nicht diskutabel.
 
Zurück
Oben