SQL 6 : Karmaşık (İç içe) SELECT Sorguları

İç içe Select sorguları, bir başka deyişle Alt Sorgu kavramı SQL‘de en zorlanılan kısımdır. Bu yazımda Alt sorgularla ilgili birkaç önemli noktaya değinerek, elimden geldiğince bol örnek yazmaya çalışacağım.

Neden İç içe Sorgu Kullanırız ?

Bir sorgudan elde ettiğiniz sonucu, diğer bir sorgu için kullanmanız gerektiğinde, iç içe sorgu kullanmanız gerekir.

Alt sorgu kavramı, genellikle birden fazla tablo söz konusu ise ortaya çıkar. Bu yüzden, örnek verebilmek amacıyla 5 adet tablo oluşturup, ilişlilerini kuralım.

Tabloların Oluşturulması ve İlişkiler

Yukarıdaki tablolar bir film veri tabanı oluşturmak için tasarlanmıştır. Biraz açıklamak gerekirse ;

Benim veri tabanımın temelinde Filmler var. Filmlerin haricinde, Film Türleri ve Filmlerde oynayan Oyuncular var.

Filmler ile Oyuncular arasında sonsuza sonsuz ilişki kurup, gereksiz veri tekrarı yapmayı önlemek amacıyla araya bir geçiş tablosu yaptım. Bu şekilde veri tekrarını minimize ettim. Aynı şeyi Filmler ile Türler arasında da yaptım.

İlişkileri bu şekilde kurduktan sonra, alt sorgu kavramına dönüp, devam edelim.

Bu veri tabanını temel alarak, dramatik filmlere ulaşmak, Tom Hanks’in filmlerine ulaşmak ya da adı “The” ile başlayan bilim kurgu filmlerine ulaşmak gibi birden fazla tabloyu ilgilendiren sorguları, alt sorgu kavramı ile yapabilirsiniz. Ya da JOIN komutlarını kullanmalısınız.

Örnek bir alt sorgu yapalım ve bize Tom Hanks’in oynadığı filmleri getirsin ;

SELECT Ad
FROM Filmler
WHERE Film_ID IN (
   SELECT Film_ID
   FROM Oyuncu_Film
   WHERE Oyuncu_ID = (
      SELECT Oyuncu_ID
      FROM Oyuncular
      WHERE Ad = "Tom" AND Soyad = "Hanks"
) )

Bu kod şu an biraz karışık görünebilir ama alt sorgu sözdizimini(syntax) görmeniz açısından ekledim.

Bu kodda her bir alt SELECT, bir üsttekine değer göndermektedir. Üstteki sorgu o değeri alıp kullanır. Zaten iç içe select sorgularının mantığı da bu değil midir ?

Aşağıda iç içe sorgular ile bilinmesi gereken noktalar var ;

  • Alt sorgu, bir üstteki sorguda yer alan WHERE, HAVING veya FROM kelimeleri içine yazılırlar. Yukarıda WHERE içinde bir alt sorgu ve onun altındaki WHERE içine de bir başka alt sorgu yazılmıştı.
  • Alt sorgular parantez işaretleri içerisinde yazılmalıdır.
  • Alt sorgularda ORDER BY komutu kullanılamaz, ancak ana sorguda kullanabilirsiniz.

WHERE ve HAVING ile alt sorguya geçerken, alt sorgunun üstteki sorguya göndereceği değer tek de olabilir birden fazla da olabilir. Tek değer gönderenlere tek satır sorguları, birden fazla değer gönderenlere çoklu satır sorguları denir. Ve bu ayrıma göre WHERE ya da HAVING için kullanılan kriter belirteci farklılık gösterir.

Tek Satır Döndüren Alt Sorgular : Kriter belirteçleri =, <, > , <=, >= veya <> olabilir.

Çok Satır Döndüren Alt Sorgular : Kriter belirteçleri IN, ANY veya ALL olabilir.

Bu açıklamalardan sonra lafı fazla uzatmayıp, birkaç örnek yapalım.

Türü dram olan filmlerin Adlarını ve IMDB Puanlarını listeleyelim ;

SELECT Ad, IMDB_Puan
FROM Filmler
WHERE Film_ID IN (
   SELECT Film_ID
   FROM Film_Tur
   WHERE Tur_ID IN (
      SELECT Tur_ID
      FROM Turler
      WHERE Ad = "Dram"
) )

Açıklama : En alttaki sorguya bakılırsa, türü dram olan filmlerin Tur_ID’leri bir üstteki sorguya gönderilmiştir. Ortadaki sorgu ifadesi ise Tur_ID’si dram olan filmlerin Film_ID’lerini ana sorguya göndermiştir. Bütün kriterler bu iki alt sorgu ile sağlandıktan sonra en üstteki SELECT ifadesi ile Ad ve IMDB_Puan değerleri seçilerek listelenmiştir.

Natalia Portman’ın oynadığı film sayısını bulalım ;

SELECT COUNT(Film_ID) AS Film_Sayisi
FROM Filmler
WHERE Film_ID IN (
   SELECT Film_ID
   FROM Oyuncu_Film
   WHERE Oyuncu_ID IN (
      SELECT Oyuncu_ID
      FROM Oyuncular
      WHERE Ad = "Natalia" AND Soyad = "Portman"
) )

Açıklama : En alttaki sorguda adı Natalia soyadı Portman olan oyuncunun Oyuncu_ID’si bir üstteki sorguya gönderilmiştir. Ortadaki sorgu ise, alt sorgudan gelen Oyuncu_ID değerini barındıran filmlerin Film_ID’lerini bir üstteki sorguya göndermiştir. (Dikkat ederseniz Oyuncu_Film tablosunda 2 sütun var : Oyuncu_ID, Film_ID) Ana sorguda ise alt sorgulardaki kriterlerden geçen kayıtların sayısı, yani Natalia Portman’ın oynadığı filmlerin sayısı bulunmuştur.

IMDB Puanı, tüm filmlerin IMDB Puanlarının ortalamasından büyük olan dram filmlerin adlarını, IMDB puanlarını ve tarihlerini listeleyelim ;

SELECT Ad, Tarih, IMDB_Puan
FROM Filmler
WHERE IMDB_Puan > (
   SELECT AVG(IMDB_Puan)
   FROM Filmler )
AND Film_ID IN (
   SELECT Film_ID
   FROM Film_Tur
   WHERE Tur_ID IN (
      SELECT Tur_ID
      FROM Turler
      WHERE Ad = "Dram"
) )

Açıklama : Bu sorguda 2 farlı kriter mevcuttur : IMDB puanı, ortalamanın üstünde olan filmler ve dram filmleri.

Dramatik filmleri bulmak amacıyla en alttaki sorgudan, türü dram olan filmlerin Tur_ID’leri bir üsttekine gönderilmiştir. Bir üstteki sorguda ise, dramatik filmlerin Film_ID’lerini ana sorguya göndermiştir.

Ortalama puanların üzerindeki filmler bulmak amacıyla AVG fonksiyonu kullanarak ana sorguya bir kriter daha belirlemiş olduk. 2 kriterde sağlandığına göre artık Ad, Tarih ve IMDB_Puan değerlerini SELECT edebiliriz.

Tom Hanks’in oynadığı dramatik filmlere bakalım ;

SELECT Ad
FROM Filmler
WHERE Film_ID IN (
   SELECT Film_ID
   FROM Oyuncu_Film
   WHERE Oyuncu_ID = (
      SELECT Oyuncu_ID
      FROM Oyuncular
      WHERE Ad LIKE "Tom*" ) )
AND Film_ID IN (
   SELECT Film_ID
   FROM Film_Tur
   WHERE Tur_ID = (
      SELECT Tur_ID
      FROM Turler
      WHERE Ad LIKE "Dra*" ))

Açıklama : Bu sorgu için 5 tabloyu da kullanmamız gerekiyor. Yine 2 farklı kritere uyan filmleri listeleyeceğiz.

Önce Tom Hanks’in oynadığı filmlerin Film_ID’leri, daha sonra türü dram olan filmlerin Film_ID’leri ana sorguya gönderilmiştir. Bu 2 kriteri sağladıktan sonra SELECT ile listeleme yapabiliriz.

Sonuç – Özet

İç içe sorgular ile, alt sorgudan dönen sonucu ana sorguda kullanabilirsiniz. Bir tablodaki değerleri, diğer bir tabloya iletmek için güzel bir yoldur. Dikkat edilmesi gereken nokta, 2 tablo arasında ilişki kurulması gerektiğidir.

Bir sorgudan diğerine geçerken, WHERE, HAVING ve FROM sözcükleri kullanılır.

Benzer Yazılar

Yorumlar

Yorum Yazın

Su elementleri kullanabilirsiniz : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Arama
RSS
Beni yukari isinla