Anasayfa / Yazılım / SQL / Alt Sorgu veya Join Kullanarak Veri Silme

Alt Sorgu veya Join Kullanarak Veri Silme

Bir tablodan Join deyimi ile birlikte DELETE kullanarak bir satır veri silebiliriz. Tabi tek satır veri silinebilir. Genelde alt sorgu ile silme tercih edilir. Söz dizimi olarak aşağıdaki gibi kullanımı vardır :

DELETE TakmaAd FROM tablo1 AS TakmaAd INNER JOIN tablo2 ON TakmaAd.kolon1 = tablo2.kolon2 WHERE şart

Burada bir takma ad yani istenilen bir isim kullanılır. WHERE deyimi opsiyoneldir, yani bir şarta bağlı silme işlemi gerçekleştirilecek ise kullanılır. INNER JOIN kullanılabildiği gibi, OUTER JOIN’de kullanılabilir.

Alt sorgu kullanarak silme işlemi için söz dizimi :

DELETE FROM tablo1 WHERE kolon1 IN (SELECT kolon2 FROM tablo2)

İlk kullanılan FROM opsiyoneldir, isterseniz kullanmayabilirsiniz.

Şimdi örnekler ile konuyu pekiştirelim. AdventureWorks2012 veri tabanı üzerinde çalışıyorum. Daha önceki yazımdan itibaren takip etti iseniz bir takım demolar oluşturmuştuk. Bu demo tablolar üzerinde işlem yapacağım. Ama takip etmeyenler için demo tabloları oluşturmaları için ilgili SQL kodları tekrar paylaşıyorum.

USE AdventureWorks2012;
GO
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[demoProduct]')
AND type in (N'U'))
DROP TABLE [dbo].[demoProduct];
GO
SELECT * INTO dbo.demoProduct FROM Production.Product;
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[demoCustomer]')
AND type in (N'U'))
DROP TABLE [dbo].[demoCustomer];
GO
SELECT * INTO dbo.demoCustomer FROM Sales.Customer;
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[demoAddress]')
AND type in (N'U'))
DROP TABLE [dbo].[demoAddress];
GO
SELECT * INTO dbo.demoAddress FROM Person.Address;
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[demoSalesOrderHeader]')
AND type in (N'U'))
DROP TABLE [dbo].[demoSalesOrderHeader];
GO
SELECT * INTO dbo.demoSalesOrderHeader FROM Sales.SalesOrderHeader;
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[demoSalesOrderDetail]')
AND type in (N'U'))
DROP TABLE [dbo].[demoSalesOrderDetail];
GO
SELECT * INTO dbo.demoSalesOrderDetail FROM Sales.SalesOrderDetail;

Bu kodu çalıştırında tablolarım oluşturulur.

2013041602

2013041603

Şimdi örneklerimize geçelim. İlk örneğimde INNER JOIN kullanarak silme işlemi yapacağım. Ama önce silinecek verilerimizi görelim. Bakalım kaç tane?

SELECT test.SalesOrderID, SalesOrderNumber FROM dbo.demoSalesOrderDetail AS test
INNER JOIN dbo.demoSalesOrderHeader AS test2 ON test.SalesOrderID = test2.SalesOrderID
WHERE test2.SalesOrderNumber = 'SO71800';

Ben sorgumda demoSalesOrderDetail tablosu ile demoSalesOrderHeader tabloları üzerinde işlem yapıyorum. Burada bu iki tabloyu birleştirme kriterim SalesOrderID kolonudur. Her iki tablo içinde takma ad yani alias kullandım. Listelenen veriler ise SalesOrderNumber değeri SO71800 olanlar. Toplam listelenen veri satırı 23 adet.

2013041703

Şimdi ben aynı mantıkla bu iki tablo üzerinde iki tbaloyu birleştirerek bunlar içinde SalesOrderNumber değeri SO71800 olanları sileceğim. Bunun için sorgum :

DELETE test FROM dbo.demoSalesOrderDetail AS test 
INNER JOIN dbo.demoSalesOrderHeader AS test2 ON test.SalesOrderID = test2.SalesOrderID
WHERE test2.SalesOrderNumber = 'SO71800';

Bu sefer silme işlemini yaptım. Aldığım mesaj : (23 row(s) affected)

Bir bakalım cidden silinmiş mi? İlk sorguyu tekrar yazıyorum.

SELECT test.SalesOrderID, SalesOrderNumber FROM dbo.demoSalesOrderDetail AS test
INNER JOIN dbo.demoSalesOrderHeader AS test2 ON test.SalesOrderID = test2.SalesOrderID
WHERE test2.SalesOrderNumber = 'SO71800';

Geriye sonuç dönmüyor. Görüleceği üzere işlem tamam.

2013041704

Aynı şekilde OUTER JOIN kullanarak da bu şekilde işlem yapabiliriz, hiç bir farkı yok.

Şimdi birde alt sorgu ile örnek yapalım.

SELECT SalesOrderID, ProductID FROM dbo.demoSalesOrderDetail WHERE ProductID NOT IN
(SELECT ProductID FROM dbo.demoProduct WHERE ProductID IS NOT NULL);

Bu sorgumda alt sorgu mantığı uyguluyorum. Listelenen veriler 121248 satır.

2013041705

Şimdi bu listelenenleri silelim.

DELETE FROM dbo.demoSalesOrderDetail WHERE ProductID NOT IN 
(SELECT ProductID FROM dbo.demoProduct WHERE ProductID IS NOT NULL);

Sorgu çalışınca 121248 satır silindi. Şimdi bir bakalım cidden silinmiş mi? İlk sorguyu tekrar yazıyorum.

SELECT SalesOrderID, ProductID FROM dbo.demoSalesOrderDetail WHERE ProductID NOT IN
(SELECT ProductID FROM dbo.demoProduct WHERE ProductID IS NOT NULL);

Ve bu sefer geriye sorgu dönmüyor.

2013041706

INNER JOIN kullanarak yapmış olduğum örnekte bir takma ad yani bir alias kullandım ama illa bi alias kullanma zorunluluğum yok, bir tablo adı vererek de silme işlemi yapabilirim. Örneğin o sorguyu alis kullanmadan yazarsam

DELETE dbo.demoSalesOrderDetail FROM dbo.demoSalesOrderDetail AS test 
INNER JOIN dbo.demoSalesOrderHeader AS test2 ON test.SalesOrderID = test2.SalesOrderID
WHERE test2.SalesOrderNumber = 'SO71800';

Tabi bu genelde önerilmez, eğer join kullanacaksanız alias kullanın. Çünkü silme işlemi önemli bir işlem ve yanlışlık affetmez 🙂

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir