T-SQL Ninja #16

UPDATE FROM

Was ist UPDATE FROM?

Wenn Ihr Werte in Tabellen UPDATEn möchtet, dann sieht ein Skript oftmals so aus, dass Ihr einer Spalte einen neuen Wert (der sich auch aus anderen Werten ableiten kann) zuweist. Doch wie funktioniert das, wenn die anderen Werte aus einer anderen Tabelle kommen? Dann braucht ihr ein UPDATE FROM.

Wie könnt ihr mit UPDATE FROM arbeiten?

Beginnen wir mit einem einfachen Update, erhöhen wir in der Wideworld Importers Datenbank den UnitPrice aller USB-Produkte in der Warehouse StockItems-Tabelle um 10%:

UPDATE Warehouse.StockItems
SET UnitPrice = UnitPrice*1.1 
WHERE StockItemName LIKE '%USB%'

SELECT @@ROWCOUNT

Damit haben wir den Preis von 14 Produkten erhöht. Nun möchten wir im Sales-Schema die OrderLines anpassen mit den neuen Preisen (auch wenn das natürlich kein Real-World-Szenario darstellt, da wir da keine abgeschlossenen Bestellungen ändern würden). Wir könnten jetzt natürlich ein Konstrukt machen, das wie folgt aussieht

UPDATE Sales.OrderLines
SET UnitPrice = UnitPrice*1.1
WHERE StockItemID IN
(
    SELECT StockItemID 
    FROM Warehouse.Stockitems 
    WHERE StockItemName LIKE '%USB%'
)

Das ist allerdings insofern etwas unschön als wir hier einerseits die Berechnung explizit anwenden müssten und dass wir andererseits den Filter auf die USB-Items wieder direkt gesetzt haben. Das können wir umgehen, indem wir einen JOIN verwenden, um die Items mit geänderten Preisen zu finden:

SELECT 
     ol.[OrderLineID]
    ,ol.[OrderID]
    ,ol.[StockItemID]
    ,ol.[Description]
    ,ol.[PackageTypeID]
    ,ol.[Quantity]
    ,ol.[UnitPrice]
    ,ol.[TaxRate]
    ,ol.[PickedQuantity]
    ,ol.[PickingCompletedWhen]
    ,ol.[LastEditedBy]
    ,ol.[LastEditedWhen] 
FROM Sales.OrderLines ol  
INNER JOIN Warehouse.StockItems si 
ON ol.StockItemID = si.StockItemID
AND si.UnitPrice <> ol.UnitPrice

Diesen JOIN können wir nun auch verwenden, um die Preise auf den 14.834 OrderLines zu ändern, bei denen die Preise nicht mehr zur aktualisierten StockItems-Tabelle passen:

UPDATE ol
SET UnitPrice = si.UnitPrice
FROM Sales.OrderLines ol  
INNER JOIN Warehouse.StockItems si 
ON ol.StockItemID = si.StockItemID
AND si.UnitPrice <> ol.UnitPrice

SELECT @@ROWCOUNT

Zusammen mit CTEs und allen möglichen JOIN– und WHERE-Bedingungen ergeben sich so die interessantesten UPDATE-Konstrukte. Es empfiehlt sich bei einem solchen UPDATE (wie generell bei jedem UPDATE) allerdings, eine Runde im Dojo zu drehen und zunächst per SELECT zu prüfen, ob denn nun auch wirklich nur die Zeilen aktualisiert werden, die auch aktualisiert werden sollen…

Referenzen:

Ninja-Notebooks @ GitHub

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.