Alt Sorgular
Örnek: Kiralama oranı (rental_rate) ortamalama kiralama oranından daha yüksek
olan filmlere iki adımda ulaşabiliriz.
1-SELECT ifadesini ve AVG (ortalama ) fonksiyonunu kullanarak ortalama kiralama oranı
(AVG(rental_rate)) bulunur.
SELECT AVG (rental_rate) FROM film; (The result returns 2.98.)
2-Bulduğumuz bu AVG(rental_rate)değerini ikinci sorguda WHERE koşulu ile
kullanarak ortalamanın üstündeki filmleri listeleyebiliriz.
SELECT film_id, title, rental_rate FROM film WHERE rental_rate > 2.98;
Bu şekilde iki adımda ulaşmak yerine, alt sorgu ile tek seferde, istenen sonuca ulaşmak
mümkündür.
SELECT film_id, title, rental_rate FROM film WHERE rental_rate > (SELECT AVG (rental_rate) FROM film) ORDER BY rental_rate;
Parantez içindeki sorguya alt sorgu veya iç sorgu denir.
Alt sorguyu içeren sorgu, dış sorgu olarak bilinir.
PostgreSQL, bir alt sorgu içeren sorguyu aşağıdaki sırayla çalıştırır ;
1-İlk olarak, alt sorguyu çalıştırır.
2-Sonucu alır ve dış sorguya iletir.
3-Dış sorguyu yürütür.
Örnek : return_date (iade tarihi ) ‘2005-05-30’ ile ‘2005-05-29’ arasında olan
filmlerin listelenmesi.
return_date, film_id ve title(film ismi) değerlerine ihtiyaç var.
film_id ve return_date kolonlarını baz alırsak her iki kolonun da bulunduğu bir
tablo olmadığı için alt sorgu (subquery) ve birleştirme (inner join ) fonksiyonlarını
kullanabiliriz.
- film_id değeri film tablosunda ve inventory tablosunda bulunmakta.
- return_date değeri de rental tablosunda bulunmakta.
- Rental tablosu ile inventory tablosunun ortak kolonu olan inventory_id
eşleştirme için kullanılabilir.
Öncelikle rental ve inventory tablosunda eşit olan inventory_id değerleri
bulunur. Bu eşit olan değerlerden where koşuluna uygun olanlar tutulur.
Inventory tablosunda tutulan inventory_id değerlerine karşılık gelen film_id
değerleri seçilir.
Bulduğumuz bu film_id değerlerini IN fonksiyonu ile kullanıp istediğimiz tarihlerde
iade edilecek olan filmleri ve başlıkları film tablosundan çekip sıralarız.
Sonuç:
SELECT film_id, title FROM film WHERE film_id IN ( SELECT inventory.film_id FROM rental INNER JOIN inventory ON inventory.inventory_id = rental.inventory_id WHERE return_date BETWEEN '2005-05-29' AND '2005-05-30' )
Bu sorgu ile aynı sonucu döndürecek sorgulara örnek verecek olursak;
SELECT film.film_id, film.title FROM film INNER JOIN inventory ON inventory.film_id = film.film_id INNER JOIN rental ON rental.inventory_id = inventory. inventory_id WHERE rental.return_date BETWEEN '2005-05-29' AND '2005-05-30' ;
Örnek : Ödeme miktarı (amount) 0.99 olan müşterilerin rental_date, rental_id
ve ödeme miktarlarını getiren sorgu.
SELECT rental.rental_date, rental.rental_id, payment.amount FROM rental INNER JOIN payment USING(rental_id) WHERE rental_id IN(SELECT rental_id from payment where amount = 0.99) ORDER BY rental_date;
Örnek : first_name değeri ‘Jared’ olan müşteriyle aynı customer_id değerine
sahip olan müşterilerin ödeme miktarlarına (amount) %50 zam yapan sorgu.
UPDATE payment SET amount = amount+amount *0.5 WHERE customer_id= (SELECT customer_id FROM customer WHERE first_name = 'Jared');
Ödeme miktarı yani amount değeri payment tablosunda first_name değeri ise
customer tablosunda bulunmakta. Bu iki tablonun ortak olan customer_id kolonundan
yola çıkıldı. Payment tablosunda değişiklik yapılacak satırlar customer_id değeriyle
koşullandırıldı. Alt sorgu ile ‘Jared’ isimli müşterinin customer_id değeri elde edildi.
Örnek : ‘ Chamber Italian’ adlı filmi kiralayan müşterilerin yapacağı ödemeye %20
zam yapan sorgu adım adım şu şekildedir. (İç içe kullanılan sorgular tek tek adım adım
açıklanmıştır.) Sorgu için ilişkili tablolar bulunmalı ve kullanılmalıdır.
1-Filmin isminden yola çıkarak film_id değeri ve buna karşılık gelen inventory_id
değerleri öğrenilir.
SELECT inventory_id, film_id FROM inventory WHERE film_id=(SELECT film_id FROM film WHERE title = 'Chamber Italian') ;
2- Bulunan inventory_id değerleri kullanılarak filmin rental_id değeri öğrenilir.
Inventory_id değerlerinin kullanılabilmesi için bir önceki sorgu alt sorgu olur.
SELECT rental_id ,inventory_id FROM rental WHERE inventory_id OF (SELECT inventory_id FROM inventory WHERE film_id= (SELECT film_id from film WHERE title ='Chamber Italian'));
3-Elde edilen rental_id değerleri payment tablosunda kullanılır. Payment tablosunda bu
rental_id değerlerine karşılık gelen amount değerlerine %20 zam uygulanır. Rental_id
değerlerinin kullanılabilmesi için bir önceki sorgu alt sorgu olur.
UPDATE payment SET amount=amount+amount*0.2
WHERE rental_id IN(SELECT rental_id FROM rental
WHERE inventory_id IN
(SELECT inventory_id from inventory
where film_id=(SELECT film_id from film
WHERE title ='Chamber Italian'))) returning *;
returning ifadesi ile değişiklik yapılan satırları görmek mümkün.
Başka ilişkili tablolar kullanılarak aynı sonucu verecek başka sorgular yazılabilir.
