UNION ve UNION ALL
SQL Server’da birden fazla sonuç kümesini birleştirmemiz gerektiğinde UNION veya UNION ALL işlemleri kullanılır. Mesela internet satışları ile mağaza satışları farklı tablolarda olan bir veritabanı düşünelim. Toplam satışları listelemek için bu iki tablonun birleşimi gerekir. UNION ve UNION ALL operatörlerini kullanırken dikkat etmemiz gereken hususlar şu şekildedir.
- Bütün sonuç kümelerindeki sütun sayısı aynı olmalıdır.
- Sıra olarak birbirine karşılık gelen sütunların veri tipleri birbirleriyle uyumlu olmalıdır.
UNION ile UNION ALL arasındaki tek fark UNION ALL ifadesi iki sonuç kümelerini direk alt alta eklerken, UNION ifadesi aynı olan kayıtlardan sadece bir tanesini getirir. Eğer birleşim için kullanacağımız sonuç kümelerinde ortak kayıtlar yoksa UNION ile UNION ALL aynı sonucu getirir. Aralarındaki performans farkını makalenin sonunda açıklayacağız.
UNION ve UNION ALL ile ilgili örneklere geçelim.
Öncelikle 2 adet örnek tablo oluşturalım.
CREATE TABLE Deneme (ID INT IDENTITY, Ad NVARCHAR(20), Soyad NVARCHAR(50), Tarih DATE) INSERT Deneme VALUES ('Hakan','Gürbaşlar','2017-01-01'),('Nurullah','Çakır','2017-01-01'),('Faruk','Erdem','2017-01-01') CREATE TABLE Deneme2 (ID INT IDENTITY, Ad NVARCHAR(20), Soyad NVARCHAR(50), Tarih DATE) INSERT Deneme2 VALUES ('Hakan','Gürbaşlar','2015-01-01'),('Nurullah','Çakır','2016-01-01'),('Faruk','Erdem','2017-01-01')
İlk olarak UNION ile UNION ALL arasındaki sonuç farkını görelim.
SELECT Ad,Soyad FROM Deneme UNION ALL SELECT Ad,Soyad FROM Deneme2
SELECT Ad,Soyad FROM Deneme UNION SELECT Ad,Soyad FROM Deneme2
Bu örnekte görüldüğü gibi UNION kullanımıyla tekrarlayan kayıtlar birer kez getirildi.
Farklı sayıda kolona sahip iki sonuç kümesini birbirine bağlamayı denediğimizde ise aşağıdaki gibi bir hata alırız.
SELECT Ad,Soyad,ID FROM Deneme UNION ALL SELECT Ad,Soyad FROM Deneme2
Sorguyu biraz değiştirelim. İlk sorguda Ad,Soyad ; ikinci sorguda Soyad,Ad sırasıyla getirelim. Veri tipleri aynı olduğu için UNION işleminde hata ile karşılaşmayacağız.
SELECT Ad,Soyad FROM Deneme UNION ALL SELECT Soyad,Ad FROM Deneme2
İlk sorguda Ad,Soyad,ID ; ikinci sorguda Ad,Soyad,Tarih alanlarını kullanarak UNION işlemini yaptığımızda ise veri tipi uyuşmazlığından kaynaklı bir hata alırız.
SELECT Ad,Soyad,ID FROM Deneme UNION ALL SELECT Ad,Soyad,Tarih FROM Deneme2
Tarih alanlarının sadece yıl kısımlarını alarak UNION işlemini yapalım.
SELECT Ad,Soyad,YEAR(Tarih) FROM Deneme UNION ALL SELECT Ad,Soyad,YEAR(Tarih) FROM Deneme2
İki sorguda ortak kayıt yoksa UNION ile UNION ALL aynı sonucu getirir demiştik. Peki bu iki sorgunun performans değerleri nasıl?
SELECT Ad,Soyad FROM Deneme WHERE Ad='Hakan' UNION ALL SELECT Ad,Soyad FROM Deneme2 WHERE Ad='Nurullah' --------------------------- SELECT Ad,Soyad FROM Deneme WHERE Ad='Hakan' UNION SELECT Ad,Soyad FROM Deneme2 WHERE Ad='Nurullah'
Yukarıdaki iki sorguda da ortak kayıt olmadığı için sonuç aynı olacaktır. Çalışma planlarını incelediğimizde UNION işleminde Distinct Sort işlemi yani tekrarlayan kayıtları temizleme işlemi yapıldığı için Sorgu maliyeti neredeyse 3 katına çıkıyor. Bu nedenle de ortak kayıtların olmadığına emin olduğumuz durumlarda mutlaka UNION ALL kullanmalıyız.