799 Stimmen

SQL-Update-Abfrage mit Joins

Ich muss ein Feld mit einem Wert aktualisieren, der durch eine Verknüpfung von 3 Tabellen zurückgegeben wird.

select
    im.itemid
    ,im.sku as iSku
    ,gm.SKU as GSKU
    ,mm.ManufacturerId as ManuId
    ,mm.ManufacturerName
    ,im.mf_item_number
    ,mm.ManufacturerID
from 
    item_master im, group_master gm, Manufacturer_Master mm 
where
    im.mf_item_number like 'STA%'
    and im.sku=gm.sku
    and gm.ManufacturerID = mm.ManufacturerID
    and gm.manufacturerID=34

Ich möchte die mf_item_number Feldwerte der Tabelle item_master mit einem anderen Wert, der mit der obigen Bedingung verbunden ist.

Wie kann ich dies in MS SQL Server tun?

1voto

Yashar Aliabbasi Punkte 2374

Sie können aktualisieren mit MERGE Befehl mit viel mehr Kontrolle über MATCHED y NOT MATCHED :(Ich habe den Quellcode leicht verändert, um meinen Standpunkt zu verdeutlichen)

USE tempdb;
GO
IF(OBJECT_ID('target') > 0)DROP TABLE dbo.target
IF(OBJECT_ID('source') > 0)DROP TABLE dbo.source
CREATE TABLE dbo.Target
    (
      EmployeeID INT ,
      EmployeeName VARCHAR(100) ,
      CONSTRAINT Target_PK PRIMARY KEY ( EmployeeID )
    );
CREATE TABLE dbo.Source
    (
      EmployeeID INT ,
      EmployeeName VARCHAR(100) ,
      CONSTRAINT Source_PK PRIMARY KEY ( EmployeeID )
    );
GO
INSERT  dbo.Target
        ( EmployeeID, EmployeeName )
VALUES  ( 100, 'Mary' );
INSERT  dbo.Target
        ( EmployeeID, EmployeeName )
VALUES  ( 101, 'Sara' );
INSERT  dbo.Target
        ( EmployeeID, EmployeeName )
VALUES  ( 102, 'Stefano' );

GO
INSERT  dbo.Source
        ( EmployeeID, EmployeeName )
VALUES  ( 100, 'Bob' );
INSERT  dbo.Source
        ( EmployeeID, EmployeeName )
VALUES  ( 104, 'Steve' );
GO

SELECT * FROM dbo.Source
SELECT * FROM dbo.Target

MERGE Target AS T
USING Source AS S
ON ( T.EmployeeID = S.EmployeeID )
WHEN MATCHED THEN
    UPDATE SET T.EmployeeName = S.EmployeeName + '[Updated]';
GO 
SELECT '-------After Merge----------'
SELECT * FROM dbo.Source
SELECT * FROM dbo.Target

0voto

FFFffff Punkte 412

Lassen Sie mich nur eine Warnung zu all den vorhandenen Antworten hinzufügen:

Wenn Sie die SELECT ... FROM-Syntax verwenden, sollten Sie bedenken, dass es sich um eine proprietäre Syntax für T-SQL handelt und nicht-deterministisch . Das Schlimmste daran ist, dass man keine Warnung oder Fehlermeldung erhält, sondern dass alles reibungslos abläuft.

Eine ausführliche Erklärung mit Beispielen finden Sie in der Dokumentation :

Seien Sie vorsichtig, wenn Sie die FROM-Klausel angeben, um die Kriterien für den Aktualisierungsvorgang festzulegen. Die Ergebnisse einer UPDATE-Anweisung sind undefiniert, wenn die Anweisung eine FROM-Klausel enthält, die nicht so spezifiziert ist, dass für jedes aktualisierte Spaltenvorkommen nur ein Wert verfügbar ist, d. h. wenn die UPDATE-Anweisung nicht deterministisch ist.

0voto

Darrel Lee Punkte 2117

Ich habe schon immer versucht, solche Dinge zu tun, und es ist mir gerade eingefallen, die folgende Syntax zu verwenden (mit Tupeln)

update dstTable T
set (T.field1, T.field2, T.field3) = 
       (select S.value1, S.value2, S.value3
        from srcTable S
         where S.key = T.Key);

Und überraschenderweise hat es funktioniert. Ich verwende Oracle (12c, glaube ich). Ist dies Standard-SQL oder Oracle-spezifisch?

NB: In meinem Beispiel aktualisiere ich die gesamte Tabelle (indem ich neue Spalten einfüge). Die Aktualisierung hat keine Where-Klausel, so dass alle Zeilen aktualisiert werden. Ihre Felder werden auf NULL gesetzt, wenn die Subquery keine Zeile zurückgibt. (und sie darf nicht mehr als eine Zeile zurückgeben).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X