WITH komutu ile, alt sorgulara isim atamak ve bu alt sorguyu diğer alt sorgularda atanan isim ile kullanmak mümkündür. Kendisini tanımladığınız alt sorgu dışındaki bütün alt sorgularda kullanılabilmektedir.
WITH komutu, aynı alt sorguya bir kaç yerde baş vurmak gerektiği durumlarda, kod tekrarı yapmadan işlem yapabilmeyi sağlamaktadır. Bu şekilde sorgular hem daha okunur olmakta, hem de optimize çalışmaktadır.
Genel Kullanımı
with sorgu_1 as (select * from table1 where ...),
sorgu_2 as (select * from table2 where ...),
...
select * from sorgu_1, sorgu_2,... where ....
Örneğimiz şu şekilde olacaktır;
Özel bir şirkette performans ve mesai prim ödemesi yapılacaktır. Bir personelin 1000 TL’lik performans primini alabilmesi için performans puanının 80 ve üzerinde olması ve çalıştığı birimin de performans ortalaması 80 ve üzerinde olması gerekmektedir. Personelin 500 TL’lik mesai primini alabilmesi için 30 saat ve üzerinde mesai yapmış olması ve birim ortalama mesai saatinin de 30 saat ve üzerinde olması gerekmektedir. Her iki primi hak eden personel sadece performans primini yani 1000 TL alabilecektir. Bu şartlara göre prim alacak personelleri ve alacağı prim tutarını getiren sql sorgumuzu yazalım.
Kullanacağımız tabloları oluşturup örnek kayıtlar ekleyelim.
create table BIRIM ( birim_id NUMBER, birim_adi VARCHAR2(50) ) ; insert into BIRIM (birim_id, birim_adi) values (1, 'Muhasebe'); insert into BIRIM (birim_id, birim_adi) values (2, 'İnsan Kaynakları'); insert into BIRIM (birim_id, birim_adi) values (3, 'Ar-ge');
create table PERSONEL ( personel_id NUMBER, adi VARCHAR2(50), soyadi VARCHAR2(50), birim_id NUMBER ) ; insert into PERSONEL (personel_id, adi, soyadi, birim_id) values (1, 'Koray', 'Uzun', 3); insert into PERSONEL (personel_id, adi, soyadi, birim_id) values (2, 'Ayşe', 'Özer', 1); insert into PERSONEL (personel_id, adi, soyadi, birim_id) values (3, 'Metin', 'Yurttaş', 2); insert into PERSONEL (personel_id, adi, soyadi, birim_id) values (4, 'Eda', 'Kürkçü', 3); insert into PERSONEL (personel_id, adi, soyadi, birim_id) values (5, 'Sedef', 'Çakır', 3); insert into PERSONEL (personel_id, adi, soyadi, birim_id) values (6, 'Osman', 'Aydın', 1); insert into PERSONEL (personel_id, adi, soyadi, birim_id) values (7, 'Hakan', 'Genç', 2);
create table PERFORMANS ( personel_id NUMBER, puan NUMBER ) ; insert into PERFORMANS (personel_id, puan) values (1, 80); insert into PERFORMANS (personel_id, puan) values (2, 60); insert into PERFORMANS (personel_id, puan) values (3, 80); insert into PERFORMANS (personel_id, puan) values (4, 90); insert into PERFORMANS (personel_id, puan) values (5, 80); insert into PERFORMANS (personel_id, puan) values (6, 90); insert into PERFORMANS (personel_id, puan) values (7, 95);
create table MESAI ( personel_id NUMBER, mesai_saati NUMBER ) ; insert into MESAI (personel_id, mesai_saati) values (4, 0); insert into MESAI (personel_id, mesai_saati) values (1, 40); insert into MESAI (personel_id, mesai_saati) values (2, 20); insert into MESAI (personel_id, mesai_saati) values (3, 5); insert into MESAI (personel_id, mesai_saati) values (5, 45); insert into MESAI (personel_id, mesai_saati) values (6, 50); insert into MESAI (personel_id, mesai_saati) values (7, 60);
WITH işlevini kullanarak istenen kayıtları bulan sql;
with
birim_ortalama as -- Bütün birimlerin ortalama performans ve mesaisi bulunuyor
(select b.birim_id,
b.birim_adi,
sum(puan) / count(*) performans_ort,
sum(mesai_saati) / count(*) mesai_ortalama
from birim b, personel p, performans r, mesai m
where b.birim_id = p.birim_id
and p.personel_id = r.personel_id
and p.personel_id = m.personel_id
group by b.birim_id, b.birim_adi),
performans_prim as -- Prim alacak personeller bulunuyor
(select '1000 TL' as prim_tutar, p.personel_id, p.adi, p.soyadi, p.birim_id
from personel p, performans r
where p.personel_id = r.personel_id
and r.puan >= 80
-- Personelin birim ortalamasının da >=80 kontrolü
and exists (select *
from birim_ortalama bo
where bo.birim_id = p.birim_id
and bo.performans_ort >= 80)),
mesai_prim as -- -- Prim alacak personeller bulunuyor
(select '500 TL' as prim_tutar, p.personel_id, p.adi, p.soyadi, p.birim_id
from personel p, mesai m
where p.personel_id = m.personel_id
and m.mesai_saati >= 30
-- Personelin birim ortalamasının da >=30 kontrolü
and exists (select *
from birim_ortalama bo
where bo.birim_id = p.birim_id
and bo.mesai_ortalama >= 30))
select *
from performans_prim --performans_prim olarak adlandırdığımız sorguyu listele
union
select *
from mesai_prim mp --mesai_prim olarak adlandırdığımız sorguyu listele
where not exists (select 1 -- Performans primi alan personel mesai almasın
from performans_prim pp
where pp.personel_id = mp.personel_id);
PRIM_TUTAR PERSONEL_ID ADI SOYADI BIRIM_ID 1000 TL 1 Koray Uzun 3 1000 TL 3 Metin Yurttaş 2 1000 TL 4 Eda Kürkçü 3 1000 TL 5 Sedef Çakır 3 1000 TL 7 Hakan Genç 2 500 TL 6 Osman Aydın 1