DERS 10: SET OPERATÖRLERİNİN KULLANIMI – Ismail Aktaş
Set operatörleri iki ya da daha fazla sorguyu birleştirir. Set operatörlerinin bulunduğu sorgulara birleşik sorgular (compound queries) denir. 4 tane set operatörü bulunmaktadır. Bunlar union, union all, intersect ve minus operatörleridir. Bu operatörler küme işlemlerinde kullanılır.
Union Operatörü: İki sorguyu birleştirir ve sonucunu döndürür. Tekrar eden satırları bir kere getirir. Union operatörü sonuçları distinct olarak getirir. Yani sonuç kümesinde 4 tane aynı isim kişi ismi gelse union operatörü tekrar eden satırları bir kere getireceğinden 1 isim gelecektir. Bu operatörü kullanırken, her bir select sorgusundan dönen kümenin aynı kolon sayısına sahip olmalıdır. Ayrıca kolonların veri tipleri ve kolonların sıraları da aynı olmalıdır.
SELECT sütun_adı FROM tablo_adı1
SELECT sütun_adı FROM tablo_adı2
Union All Operatörü: Union operatörü ile yanı işi yapar ancak tek farkı tekrar eden satırları da getirir. Yani sonuçları distinct olarak getirmez.
Intersect Operatörü: İki select cümlesinin ortak noktalarını bulmak için kullanılır. Yani farklılıkları eleyerek ortak noktalarını döndürür.
Minus Operatörü: ilk select cümlesinin ikinci select cümlesinden farkını getirir. Buradaki sıralama önemlidir. Bir nevi çıkarma işlemidir.
Bu aşamada job_history tablosu üzerinden de çalışmaya başlayacağız. Job_history tablosu isminden de anlaşılacağı gibi iş geçmişini tutmakta. İşe ne zaman girdikleri, birimlerini değiştirdiyse öncesinde hangi birimde olduğu, birimini değiştirdiği tarih gibi iş bilgilerini bu tabloda tutmakta. Bu tablodan bahsetmemdeki amaca gelince, set operatörlerini bu tablo ile anlatmaya çalışacağız. Örneğin employees tablosu ile job_history tablosunu birleştirerek sorgu çekeceğiz, set operatörlerini kullanacağız.
Set operatörlerindeki syntax kurallarından ve yapılabilecek hatalardan bahsetmek gerekirse, ilk olarak mutlaka ilk select cümlesinde kaç sütun adı varsa ikinci select cümlesinde de o kadar sütun olmalı. Sütun isimlerinin önemi yok ancak veri tiplerinin tutuyor olması gerekmekte. Örneklerle açıklamaya başlayalım.
İlk olarak union operatörü ile başlayalım.
SELECT employee_id, job_id FROM job_history;
Yukarıdaki sorgu ve sonucuna baktığımızda emplyees tablosu ile job_history tablosunun birleşimini almışız. Sonuç olarak çalışanların iş geçmişini görmüş olduk. Yukarıdaki sonuçta çalışanlardan 101 nolu olan çalışanın başladığı pozisyondan sonra birkaç pozisyon değişikliği olduğunu da görmüş olduk. Peki gelen sonuçlardan hangisinin employees tablosundan hangisinin job_history tablosundan geldiğini nasıl öğreniriz. Şimdi bunun için de bir örnek yapalım.
SELECT employee_id, job_id, 0 FROM employees
SELECT employee_id, job_id, 1 FROM job_history;
Sorgumuzda üçüncü bir sütun eklemiş olduk. Ve böylece job_id yanındaki sütunda 0 yazanlar employees tablosundan geldiğini, 1 yazanlarında job_history tablosundan geldiğini anlamış oluyoruz.
SELECT employee_id, job_id, hire_date, null, 0 FROM employees
SELECT employee_id, job_id, start_date, end_date, 1 FROM job_history;
Bu sorgumuzda ise job_history’deki start_date ve end_date sütunlarını kattık. Ancak sorguda hata olmaması anlamında ilk select ifadesinde de bu sütunların karşılığı olması gerekmekteydi. Bu nedenle ilk select cümlesinde yani employees tablosunun sorgusunda start_date karşılık gelen hire date’ olabilir. End_date için ise null yazarız. Sonuç tablosunda da çalışanların hangi tarihler arasında hangi departmanda görev yaptıklarını görmekteyiz. Null gelenler ise halen o işte çalıştığı anlamına gelmektedir. Ayrıca sorgularımızı incelediğimizde veriler sıralı olarak gelmiştir. O zaman union operatörü ayrıca veriyi sıralı olarak getirmektedir. Örneğe baktığımızda employee_id’yi büyükten küçüğe sıralamıştır. O zaman ilk sütuna göre union operatörü büyükten küçüğe göre sıralama işlemi yapmaktadır.
Unutmamız gereken bir soru var, gelmeyen bir kayıt olması muhtemel midir? Evet muhtemeldir. Peki gelmeyen kayıt varsa onu nasıl getirebiliriz. Union all operatörünü kullanacağız demektir.
Union All Operatörü:
Union All operatörü sıralama yapmaz ve bu nedenle union’a göre daha hızlıdır. Tekrar eden satırları teke düşürmez demiştik, konunun başında. Yani ne kadar veri varsa hepsini getirecektir. Şunu diyebiliriz union’a göre union all daha fazla satır getirecektir. Eğer sıralı bir veri istemiyorsak union all kullanmak daha performanslı olacaktır.
SELECT employee_id, job_id, department_id FROM job_history;
Yukarıdaki sorguyu incelediğimizde department_id’si null olan kişilerinde bilgilerinin geldiğini görmekteyiz.
Intersect ile iki sorgu arasında ki ortak satırları öğrenmek için kullanılan bir operatördür. Kesişimleri getirir. Otomatik olarak sıralama yapar. Bir örnek ile açıklayalım.
Yukarıdaki sorgu employees tablosundaki ve job_history’deki değerleri aynı olan verileri getiren bir sorgudur. Peki neden job_id’leri aynı olduğu halde job_history’ye gitmişler diye soracak olursak. Demek ki değişen bir şeyler var, department_id’leri değişmiş olabilir. Aynı işi yaparak departmanı değişen kişiler kimler diye soru sorulsa yukarıdaki sorgu yazılacaktır.
Bir nevi çıkarma işlemidir. İki select cümlesi arasındaki farkı getirir. Otomatik olarak sıralama yapar. Örnek ile açıklayalım.
SELECT employee_id FROM job_history;
Eğer job_hitory’ye hiç düşmemiş kişiler kimler diye sorarsak ya da job_id’si ya da department_id’si hiç değişmemiş kişiler kimler diye sorarsak yukarıdaki sorguyu yazarız.
SELECT location_id, department_name “Department”, TO_CHAR (NULL) “Warehouse location”
SELECT location_id, TO_CHAR (NULL) “department”, state_provience
Yukarıda ki sorguyu incelediğimizde bir union işlemi yapılmış. Bu işlem için departments tablosundan 2 sütun almış ve üçüncü sütun yerinde ise NULL’ü karaktere çevirerek, locations tablosundanda iki sütun ve NULL’ü karaktere çevirerek iki tabloda da olmayan sütunlar yerine null gelmesini sağlamış olduk. NULL’u karakter tipine çevirmesinin nedeni ise, diğer tabloda karşılığına gelen sütun karakter tipinde olduğu içindir. Performans için bu şekilde yapılır. Sadece NULL bile yazılsa olur.
SELECT employee_id, job_id, salary FROM departments
SELECT employee_id, job_id, 0 FROM locations;
Locations tablosunda salary olmadığı için onun yerine 0 (sıfır) gelmesi sağlanmıştır.
Sonraki yazı DERS 11: DATA MANUPULATION LANGUAGE (INSERT, UPDATE, DELETE)
Önceki yazı DERS 9: SUBQUERY (ALT SORGULAR)