Top N Sorguları İle Çalışmak (MS SQL Server vs Oracle)

Günümüzde en çok kullanılan İlişkisel Veritabanı Yönetim Sistemleri (RDBMS)’ nin başında  Microsoft SQL Server ve Oracle gelmektedir. Her iki veritabanı yönetim sistemi de şirketler tarafından sıklıkla tercih edilebilmektedir. Bir şirket kullanmakta olduğu veritabanı yönetim sistemini diğer bir veritabanı yönetim sistemine taşımak isteyebilmektedir. Bu gibi migration durumlarında veritabanını kullanan uygulamaların, migration işleminden etkilenmeden işleyişini devam ettirmesi gerekmektedir. Bu gibi durumlarda veritabanında tutulan veriler diğer sisteme taşınsa bile, veritabanı yönetim sistemine bağlı olarak uygulamaların veritabanına gönderdiği komutların da (DML, DDL vs) bu migration işlemi sırasında elden geçirilmesi gerekebilecektir. Her ne kadar Oracle ve MS SQL Server arasında, kullanılan SQL komutları ve dil yapısı arasında temel olarak çok fazla fark olmasa bile, bazı işlemleri her iki sistemde farklı komutlar ve yollar kullanarak elde etmek mümkün olabilmektedir. Bu yazımızdan itibaren belirli aralıklarla MS SQL Server‘da kullanılan T-SQL dili ve Oracle‘da kullanılan SQL ve PL/SQL dilleri üzerinde farklı şekillerde yapılabilecek işlemleri ele alıyor olacağız.

İlk olarak bu makalemizde, veritabanındaki tablolardan döndürülecek kayıtların belirli bir sayıda sınırlanmasının her iki sistemde nasıl gerçekleştirilebileceğini ele alıyor olacağız. Bu gibi sorgulara örnek olarak,

  • en son sipariş veren son 10 müşteri,
  • en son kayıt olan 5 öğrenci,
  • satılan ürünler içerisindeki en pahalı 3 ürünün tespit edilmesi,
  • bugüne kadar en çok sipariş veren ilk 100 müşterinin tespit edilmesi

gibi durumlar verilebilir. Görüldüğü üzere bu tip sorgularda hem bir şarta bağlı olarak sıralama işlemi gerçekleştirilmekte, hem de bu sıralamaya bağlı olarak döndürülecek satır sayısına bir limit, sınır verilmektedir. Literatürde bu tip sorgulara Top N sorguları denilmektedir. Şimdi bu tip sorguların her iki veritabanı yönetim sisteminde nasıl ele alınacağını hep birlikte inceleyelim:

Microsoft SQL Server:

MS SQL Server’da Top N sorgularını yazmak oldukça basittir. Bu işlemi gerçekleştirebilmek için SQL Server‘da bulunan ve SELECT komutu içinde kullanılabilen TOP ifadesi vasıtasıyla sonuç setinde döndürülecek kayıt sayısı sınırlandırılabilir. Tabi ki TOP operatörünün mantıklı bir şekilde çalışabilmesi için sorgunun ORDER BY ile istenilen şarta bağlı bir şekilde sıralanması gerekmektedir. Aşağıdaki örneği hep beraber inceleyelim:

SELECT TOP 10 SalesOrderID, CustomerID, OrderDate, SubTotal
FROM Sales.SalesOrderHeader
ORDER BY OrderDate desc

Yukarıdaki SQL sorgusunda en son verilen 10 siparişe ait detaylar getirilmektedir. Görüldüğü üzere MS SQL Server üzerinde bu işlemi yapabilmek için ORDER BY ile veriler OrderDate kolonuna göre büyükten küçüğe sıralanmış ve SELECT komutunun yanına TOP 10 ifadesi eklenerek getirilecek sonuç sayısının 10 ile sınırlandırılması sağlanmıştır. Sorgunun çıktısı aşağıdaki gibidir:

TopN_1

MS SQL Server içerisinde TOP ifadesinin yanına yukarıda olduğu gibi sadece sayı verildiğinde, döndürülecek olan satır sayısını rakamsal olarak sınırlandırmış olursunuz. Bu kullanım ile beraber TOP ifadesinin tablodaki satır sayısının belirli bir yüzdesi kadar sonuç döndürmesi için PERCENT ifadesi eklenebilmektedir. Bu durumda sorgu aşağıdaki gibi olacaktır:

SELECT TOP 20  PERCENT SalesOrderID, CustomerID, OrderDate, SubTotal
FROM Sales.SalesOrderHeader
ORDER BY OrderDate desc

MS SQL Server içerisinde TOP ifadesi ile beraber kullanılabilen diğer seçenekleri (WITH TIES gibi) ve SQL Server 2012 ile beraber gelen ve TOP işlemini biraz daha genişleten ve sayfalama imkanı yapılmasına olanak sağlayan OFFSET – FETCH komutlarını başka bir yazıya bırakarak TOP N sorgularının Oracle‘da nasıl yapılabileceğine de bir göz atalım:

Oracle:

Benzer bir şekilde üniversite öğrencilerinin kayıtlarının tutulduğu bir tablo üzerinde en son kayıt olan 10 öğrencinin getirilmesi istenildiğinde, Oracle’da TOP operatörü olmadığı için farklı bir yöntem kullanılarak bu ihtiyaç karşılanabilmektedir. Burada ROWNUM kullanılarak döndürülecek kayıt sayısı sınırlandırılabilmektedir, ancak aynı sorgu içerisinde ORDER BY ile sıralama şartı verilmesine rağmen WHERE komutu Oracle optimizeri tarafından daha önce çalıştırıldığı için istenilen sonuç tek bir sorguda elde edilememektedir. Aşağıda bu örnek (yanlış sonuç üretiyor…) görülebilir:

  SELECT student_ıd,
          fırst_name,
          last_name,
          regıstratıon_date
  FROM student
  WHERE ROWNUM <= 10
  ORDER BY regıstratıon_date DESC;

Buradaki SQL sorgusunda öncelikle WHERE komutu çalıştırılarak getirilen kayıt sayısı 10 ile sınırlandırılıyor, ardından da ORDER BY ile bu 10 kayıt büyükten küçüğe sıralandırılıyor. Böyle bir durumda istenilen sonuç elde edilemeyecek ve sonuç seti bizim açımızdan hatalı olacaktır:

TopN_3

Yukarıda üretilen ve bizim açımızdan hatalı olan sonuçları düzeltebilmek ve gerçekten en son kayıt olan 10 öğrenciyi ele alabilmek için ORDER BY komutunun önce çalıştırılması ve ardından WHERE ile kayıt sayısının sınırlandırılması gerekmektedir. Bunu gerçekleştirebilmek için de bir subquery (inline view) kullanarak önce sıralama işlemi yapılmakta ve ardından da dış sorguda döndürülecek olan sonuç seti sınırlandırılabilmektedir.

Sorgunun doğru hali aşağıdaki gibidir:

SELECT *
FROM
  (SELECT student_ıd,
          fırst_name,
          last_name,
          regıstratıon_date
  FROM student
  ORDER BY regıstratıon_date DESC
  )
WHERE ROWNUM <= 10;

Bu şekilde çalıştırılan bir sorgunun ardından tablodaki kayıtlar öncelikle registration_date kolonuna göre büyükten küçüğe sıralanacak, ardından bu iç sorgudan dönen değerler dış sorguda yer alan ROWNUM filtresi ile belirli bir adette döndürülmesi sağlanacaktır. Sorgudan dönen doğru sonuç seti aşağıdaki gibidir:

TopN_2

Oracle 11 g ve önceki versiyonlarında bu gibi TOP N sorgulama işlemleri sadece ROWNUM kullanılarak değil, aynı zamanda RANK, DENSE_RANK, ROW_NUMBER gibi fonksiyonlar vasıtasıyla da yazılabilmektedir. OVER cümlesi ile beraber kullanılan bu fonksiyonları başka bir makalemizde ele alıyor olacağız.

Ayrıca Oracle 12 c ile beraber gelen yeni bir özellik ile TOP N sorguları çok daha kolay bir şekilde yazılabilmektedir. Yukarıda yazılan sorguyu Oracle 12 c ile beraber aşağıdaki şekilde çok daha kolay bir şekilde yazabileceksiniz:

  SELECT student_ıd,
          fırst_name,
          last_name,
          regıstratıon_date
  FROM student
  ORDER BY regıstratıon_date DESC
  FETCH FIRST 10 ROWS ONLY;

Görüleceği üzere MS SQL Server ile Top N sorguları, özellikle Oracle 11 g ve öncesiyle kıyaslandığında çok daha kolay bir şekilde yazılabilmektedir. Oracle 12 c ile gelen OFFSET-FETCH komutu ile Top N sorguları artık Oracle'da da daha kolay ele alınabilmektedir. Faydalı olması dileğimle...

Yazı hakkındaki görüş, öneri ve yorumlarınızı bildirebilirsiniz. Bir sonraki yazımızda görüşmek üzere...

Yazar: Abdullah ALTINTAŞ