Update mit Verknüpfung von 2 Tabellen und Filterbedingung

basti_78

Neuer Benutzer
Beiträge
2
Hallo in die Runde!

Ich lese hier schon immer mal im Bedarfsfall mit und bräuchte jetzt mal eine kleine Unterstützung. Leider habe ich bislang keine passende Lösung gefunden.

Folgenden Sachverhalt habe ich in einer SQL-Datenbank:

Es sind 2 Tabellen vorhanden. Über einen gleichen Schlüssel (ID) soll ein Wert aus einer anderen Tabelle übernommen werden.

Beispiel:

Tabelle1
ID Zahl
1001 -1
1002 -1
1003 13
1004 -1

Tabelle2
ID Zahl Datum
1001 10 01.03.2018
1002 12 01.03.2018
1003 13 01.03.2018
1002 10 03.03.2018
1004 13 02.03.2018

(in der Anlage sieht es bißchen schöner aus) ;-)

upload_2018-8-15_11-31-14.png

Es sollen die Werte "Zahl" aus der Tabelle2 in die Tabelle1 übernommen werden, wenn in der Tabelle1 die Zahl -1 beträgt.
Eine weitere Besonderheit ist, dass in der Tabelle2 auch mehrere Datensätze zu einer ID vorhanden sein können. Hier sollte die Zahl mit dem größten Datum übernommen werden.

Ich habe es schon mit "verschachtelten" Update-Befehlen versucht, aber komme nicht so richtig zum Ergebnis bzw. der Server meckern mich an...

Beispiel:

update Tabelle1
set zahl = (select zahl from Tabelle2 where Tabelle1.id=Tabelle2.id)
where tabelle1.zahl=-1

Es kommt die Hinweismeldung:
Die Unterabfrage hat mehr als einen Wert zurückgegeben. Das ist nicht zulässig, wenn die Unterabfrage auf =, !=, <, <=, > oder >= folgt oder als Ausdruck verwendet wird.

Dann habe ich es noch mit einem JOIN versucht, aber das Ergebnis war auch nicht zufriedenstellend :-(

UPDATE Tabelle1
SET zahl = Tabelle2.zahl
FROM Tabelle1 INNER JOIN Tabelle2 ON Tabelle1.id = Tabelle2.id
where Tabelle1.zahl=-1

Könnte mir bitte jemand mit einem möglichen Befehl helfen?

Danke und viele Grüße
Basti
 
Werbung:
Code:
test=# select * from tabelle1;
  id  | zahl
------+------
 1001 |   -1
 1002 |   -1
 1003 |   13
 1004 |   -1
(4 Zeilen)

test=*# select * from tabelle2;
  id  | zahl |   datum   
------+------+------------
 1001 |   10 | 2018-03-01
 1002 |   12 | 2018-03-01
 1003 |   13 | 2018-03-01
 1002 |   10 | 2018-03-03
 1004 |   13 | 2018-02-03
(5 Zeilen)

test=# update tabelle1 set zahl = tmp.zahl from (select distinct on (id) id, datum, zahl from tabelle2 order by id, datum desc ) tmp where tabelle1.id=tmp.id and tabelle1.zahl=-1;
UPDATE 3
test=*# select * from tabelle1;
  id  | zahl
------+------
 1003 |   13
 1001 |   10
 1002 |   10
 1004 |   13
(4 Zeilen)

test=*#

paßt das so?
 
DISTINCT ON (...) ist eine der vielen Erweiterungen von PostgreSQL, die andere DB's nicht haben. Wie wäre es damit?

Code:
test=# with t1 as (select id, max(datum) from tabelle2 group by id), t2 as (select id, zahl from tabelle2 where (id, datum) in (select * from t1)) update tabelle1 set zahl=t2.zahl from t2 where tabelle1.id=t2.id and tabelle1.zahl = -1;
UPDATE 3
test=*# select * from tabelle1;
  id  | zahl
------+------
 1003 |   13
 1001 |   10
 1002 |   10
 1004 |   13
(4 Zeilen)

test=*#
 
Werbung:
Guter Lösungsansatz, ich hätte für Tabelle2 eine temp Tabelle gebastelt, in der die reinen Daten mit max(datum) stehen, ist für mich übersichtlicher und für Anfänger vielleicht besser nachzuvollziehen:

Code:
--lokale Tabelle1 erstellen für den Test, dieser Schritt ist sonst nicht notwendig
DECLARE @tabelle1_local TABLE (id INT, zahl int);
INSERT @tabelle1_local(id, zahl)
VALUES (1001, -1), (1002, -1), (1003, 13), (1004, -1);

--alte Werte anzeigen lassen zum Vergleich
SELECT * FROM @tabelle1_local;

--das ist do lokale Tabelle, die fix ist und immer aktualisert wird vom System oder was auch immer
DECLARE @tabelle2_local TABLE (id INT, zahl int, datum date);
INSERT @tabelle2_local(id, zahl, datum)
VALUES (1001, 10, '01.03.2018'), (1002, 12, '01.03.2018'), (1003, 13, '01.03.2018'), (1002, 10, '03.03.2018'),
        (1004, 13, '02.03.2018');

-- Parametertabelle mit den Daten aus "Tabelle2" füllen
DECLARE @PARMTABLE TABLE (id INT, zahl int);
INSERT @PARMTABLE(id, zahl)
SELECT t1.id, t1.zahl
FROM @tabelle2_local t1
INNER JOIN    (
            SELECT id, max(datum) as datum 
            FROM @tabelle2_local
            GROUP BY id
            ) t2 ON t1.id = t2.id AND t1.datum = t2.datum;

-- Updatebefehlt ausführen
UPDATE @tabelle1_local
SET zahl = p.zahl
FROM @PARMTABLE p, @tabelle1_local t1
WHERE p.id = t1.id;

-- Anzeige der neuen Werte
SELECT * FROM @tabelle1_local;

Hoffe vielleicht jemanden geholfen zu haben...
 
Zurück
Oben