Veritabanı Tasarımı Çoklu Satır Alt Sorgular
Konular Çoklu satır alt sorgulardaki IN, ANY ve ALL karşılaştırma operatörlerinin doğru kullanımı WHERE ve HAVING yantümcelerinde çoklu satır alt sorguları oluşturma ve çalıştırma Çoklu satır alt sorgu NULL değeri döndürürse ne olacağının açıklanması Çoklu satır alt sorgularının ne zaman kullanılacağının anlaşılması ve tek satır alt sorgularının ne zaman güvenli olduğu EXISTS ve NOT EXISTS kullanarak alt sorgudan dönen kayıtların test edilmesi 2
Amaç Bir alt sorgu size bilmek istediğiniz bilgileri bulmak için tasarlanmıştır. Ancak, tek satır alt sorgular yalnızca bir satır döndürebilir. Birkaç satır ve çeşitli değerlere dayalı bilgi bulmak isterseniz ne olur? Alt sorgu birkaç satır döndürmelidir. Çoklu satır alt sorgular ve üç karşılaştırma operatörü (IN, ANY ve ALL) kullanarak bunu başarabiliriz. 3
Sorgu Karşılaştırması 20 nolu bölümdeki çalışanın maaşına kimlerin maaşı eşit? SELECT first_name, last_name WHERE salary = (SELECT salary WHERE department_id = 20); Bu örnek neden çalışmaz? 4
Sorgu Karşılaştırması Çünkü 20 nolu bölümde birden fazla çalışan bulunmaktadır. Bu yüzden alt sorgu çok satır döndürür. Buna çoklu satır alt sorgu deriz. SELECT first_name, last_name WHERE salary = (SELECT salary WHERE department_id = 20); 5
Sorgu Karşılaştırması Sorun dış sorgunun WHERE yan tümcesindeki eşittir (=) işaretidir. Nasıl bir değer, bir seferde birden fazla (a eşit ya da değil) eşit olabilir? Bu saçma bir soru, öyle değil mi? SELECT first_name, last_name WHERE salary = (SELECT salary WHERE department_id = 20); 6
IN, ANY ve ALL Birden fazla değer döndüren alt sorgulara çoklu-satır alt sorgu denir. Tek satır karşılaştırma operatörleri (=, <, ve benzeri) kullanılamaz. Çoklu-satır alt sorgular için farklı karşılaştırma operatörlerine ihtiyaç duyarız. SELECT title, year WHERE year IN (SELECT year ); 7
IN, ANY ve ALL Çoklu satır operatörleri IN, ANY ve ALL ifadeleridir. NOT operatörü bu üç operatörden herhangi biriyle kullanılabilir. SELECT title, year WHERE year IN (SELECT year ); 8
IN IN operatörü dış sorgu WHERE yantümcesi ile birlikte kullanılır. Bu sayede iç sorgudan geri dönen değerlerin içerisinde bulunan hangi kayıtların döneceğini seçer. SELECT title, year WHERE year IN (SELECT year WHERE cd_number < 93); Örneğim CD numarası 93 ten küçük olan yıllarla aynı yıla sahip olan CD lerin başlıkları ile ilgilenelim. 9
IN 93 numaranın altındaki CD'lerin içinde hangi yıllar olduğunu bilmediğimizden, alt sorgu bizim için bu yılların listesini dönecektir. Dış sorgu daha sonra iç sorgudaki yılların listesindeki yıllarla aynı olan yılların başlıklarını döndürecektir. SELECT title, year WHERE year IN (SELECT year WHERE cd_number < 93); 10
ANY ANY operatörü alt sorgu sonuç kümesindeki değerlerden en az birine eşleşen satırların seçilmesi için dış sorgu SELECT yantümcesi kullanılmasıdır. SELECT title, producer WHERE year < ANY (SELECT year WHERE producer = 'The Music Man'); 11
ANY Bu örnekte yılı The Music Man tarafından üretilen CD yılından daha düşük olan CD başlıkları döndürülür. SELECT title, producer WHERE year < ANY (SELECT year WHERE producer = 'The Music Man'); 12
ALL ALL operatörü alt sorgu sonuç kümesindeki değerlerin tümüne eşleşen satırların seçilmesi için dış sorgu SELECT yantümcesi kullanılmasıdır. Bu örnekte yılı The Music Man tarafından üretilen CD yılından daha büyük olan tüm CD başlıkları döndürülür. SELECT title, producer,year WHERE year > ALL (SELECT year WHERE producer = The Music Man ); 13
ALL ALL operatörü iç sorgudan dönen her değer için karşılaştırma yapar. SELECT title, producer,year WHERE year > ALL (SELECT year WHERE producer = The Music Man ); 14
NULL Değerler Çok satırlı alt sorgu tarafından döndürülen değerlerden birinin boş olduğunu varsayalım, ancak diğer değerler değil. Şayet IN veya ANY kullanılırsa, dış sorgu null olmayan değerler ile eşleşen satırları dönecektir. SELECT last_name, employee_id WHERE employee_id IN (SELECT manager_id ); 15
NULL Değerler Şayet ALL kullanılırsa, dış sorgu her hangi bir satır döndürmez. Çünkü ALL, dış sorgu satırları ile alt sorgudan dönen Null içeren her değeri karşılaştırır. Null ile her hangi bir şey karşılaştırma da Null ile sonuçlanır. SELECT last_name, employee_id WHERE employee_id IN (SELECT manager_id ); 16
Alt Sorgularda NULL Değerler Şimdi, iç sorgu tarafından döndürülen değerlerin hiçbiri boş bir değer değildir. Böylece çalışır. SELECT emp.last_name emp WHERE emp.employee_id NOT IN (SELECT mgr.manager_id mgr WHERE mgr.manager_id IS NOT NULL); 17
GROUP BY ve HAVING Şüphe edebileceğiniz üzere, GROUP BY ve HAVING yantümceleri aynı zamanda çoklu satır alt sorgular ile kullanılabilir. Minimum maaşı 10. ve 20. bölümlerde çalışan her hangi bir çalışandan daha az olan bölümleri bulmak istersek ne yaparız? 18
GROUP BY ve HAVING 10 ve 20 nolu bölümlerdeki çalışanların maaşlarını döndüren çok satırlı alt sorguya ihtiyaç duyarız. Dış sorgu MIN grup fonksiyonunu kullanır ve bu yüzden department_id yegöre dış sorguyu GROUP BY yapmalıyız. 19
GROUP BY ve HAVING İhtiyaç duyulan SQL ifadesi: SELECT department_id, MIN(salary) GROUP BY department_id HAVING MIN(salary) <ANY (SELECT salary WHERE department_id IN (10,20)); 20
GROUP BY ve HAVING Hatta GROUP BY yantümcesini alt sorguda kullanabiliriz. Hangi bölümler bölüm numarası 50 den az olan bölümlerin minimum maaşlarından daha büyük minimum maaşa sahiptir? SELECT department_id, MIN(salary) GROUP BY department_id HAVING MIN(salary) >ALL (SELECT MIN(salary) WHERE department_id < 50 GROUP BY department_id); 21
Alt Sorgularla İlgili Son Nokta Bazı alt sorgular satırlardaki veri değerlerine bağlı olarak, tek bir satır veya birden çok satır döndürebilir. Hatta birden fazla satır dönmesi için ufak bir olasılık da olsa, çoklu satır alt sorgu yazdığınıza emin olun. SELECT first_name, last_name, job_id WHERE job_id = (SELECT job_id WHERE last_name = Ernst ); 22
Alt Sorgularla İlgili Son Nokta Örneğin Ernst ile kimler aynı job_id ye sahip? Bu tek satır alt sorgu düzgün bir şekilde çalışır çünkü tabloda tek Ernst vardır. Fakat daha sonra şirket Susan Ernst isimli yeni bir çalışan alırsa ne olur? SELECT first_name, last_name, job_id WHERE job_id = (SELECT job_id WHERE last_name = Ernst ); 23
Alt Sorgularla İlgili Son Nokta Bu çoklu satır alt sorgu yazmak için daha iyi olur. Sorgu tek bir satır döndürse bile çoklu satır sorgu sözdizimi çalışmaya devam edecektir. Şüpheniz varsa, bir çoklu satır alt sorgu yazın! SELECT first_name, last_name, job_id WHERE job_id IN (SELECT job_id WHERE last_name = Ernst ); 24