Ana içeriğe geç
Kesit SQL
İleri · T-SQL (SQL Server)

MERGE: eşitle, güncelle, ekle, sil

Kaynak ile hedefi tek ifadede eşitlemek.

Uygulamada aç, 3 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

Tek ifadede üç işlem

MERGE, bir kaynak tablo ile hedef tabloyu bir anahtara göre karşılaştırır: eşleşenleri günceller, hedefte olmayanları ekler, istenirse kaynakta olmayanları siler. Veri ambarı yüklemelerinin temel aracıdır.

MERGE INTO hedef AS t
USING kaynak AS s
   ON t.anahtar = s.anahtar
WHEN MATCHED [AND ek_koşul] THEN UPDATE SET ...
WHEN NOT MATCHED [BY TARGET] THEN INSERT (...) VALUES (...)
WHEN NOT MATCHED BY SOURCE THEN DELETE;   -- MERGE ; ile bitmek zorundadır

En son fiyatları ürün tablosuna işlemek

WITH son AS (
    SELECT product_id, new_price,
           ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY updated_at DESC) AS rn
    FROM price_updates
)
MERGE INTO products AS t
USING (SELECT product_id, new_price FROM son WHERE rn = 1) AS s
   ON t.product_id = s.product_id
WHEN MATCHED AND t.price <> s.new_price THEN
    UPDATE SET price = s.new_price;

SELECT p.product_id, p.name, p.price
FROM products p
WHERE p.product_id IN (SELECT product_id FROM price_updates)
ORDER BY p.product_id;

Tam eşitleme: ekle, güncelle, sil

CREATE TABLE #hedef (dept_id INT PRIMARY KEY, name NVARCHAR(50), city NVARCHAR(50));
INSERT INTO #hedef SELECT dept_id, name, city FROM departments WHERE dept_id <= 4;
UPDATE #hedef SET city = N'Eski Şehir' WHERE dept_id = 2;

MERGE INTO #hedef AS t
USING (SELECT dept_id, name, city FROM departments WHERE dept_id >= 2) AS s
   ON t.dept_id = s.dept_id
WHEN MATCHED AND t.city <> s.city THEN UPDATE SET city = s.city
WHEN NOT MATCHED BY TARGET THEN INSERT (dept_id, name, city) VALUES (s.dept_id, s.name, s.city)
WHEN NOT MATCHED BY SOURCE THEN DELETE;

SELECT * FROM #hedef ORDER BY dept_id;
DikkatKaynakta aynı anahtar birden fazla kez geçerse MERGE hata verir (“The MERGE statement attempted to UPDATE or DELETE the same row more than once”). Kaynağı önce tekilleştir (yukarıdaki ROW_NUMBER gibi). OUTPUT $action, inserted.*, deleted.* ile hangi satıra ne yapıldığını raporlayabilirsin.
Alıştırmalara geç (3)