Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Mit SQL Merge oder UPDATE / INSERT

UPDATE m SET 
  col2 = t.col2, 
  col3 = t.col3 -- etc. - all columns except Customer_Number
FROM dbo.Master_File AS m
INNER JOIN 
(
  SELECT 
    Customer_Number, rn = ROW_NUMBER() OVER
    (
      PARTITION BY Customer_Number ORDER BY [timestamp_column] DESC
    ), col2, col3, ... etc ...
  FROM dbo.Temp_Table
) AS t
ON m.Customer_Number = t.Customer_Number
WHERE t.rn = 1;

INSERT dbo.Master_File(Customer_Number, col2, col3, ...etc...)
  SELECT Customer_Number, col2, col3, ...etc...
  FROM 
  (
    SELECT 
      Customer_Number, rn = ROW_NUMBER() OVER 
      (
        PARTITION BY Customer_Number ORDER BY [timestamp_column DESC
      ),
      col2, col3, ...etc...
    FROM dbo.Temp_Table AS t 
    WHERE NOT EXISTS 
    (
      SELECT 1 FROM dbo.Master_File AS m
      WHERE m.Customer_Number = t.Customer_Number
    )
  ) AS x WHERE rn = 1;

Dadurch werden mehrere Zeilen in der Quelltabelle behandelt, die im Ziel noch nicht vorhanden sind. Ich habe eine Annahme über Spaltennamen gemacht, die Sie anpassen müssen.

MERGE mag verlockend sein, aber es gibt ein paar Gründe, warum ich davor zurückschrecke:

  1. Die Syntax ist entmutigend und schwer zu merken...
  2. Sie ziehen an Sie erhalten nicht mehr Parallelität als der obige Ansatz, es sei denn, Sie fügen absichtlich spezifische Sperrhinweise hinzu ...
  3. es gibt viele ungelöste Fehler mit MERGE und wahrscheinlich viele weitere, die noch entdeckt werden müssen...

Ich habe kürzlich einen Warnhinweis veröffentlicht auch hier und haben hier einige andere Meinungen gesammelt .