Merhaba,
Bu yazımda Oracle ile kod geliştirirken bazı durumlarda bir kaydın belirli bir düzen içerisinde kendinden sonraki kayıtla eşleşmesi gereken durumlarda bu işi PL/SQL dilinde nasıl yapacağımızı anlatacağım. Bu işlemin birden fazla yolu olabilir fakat ben bu yazının konusu olarak PL/SQL'de kullanılan RANK fonksiyonu basitce anlatmak ve bu fonksiyonu kullanarak neler yapılabileceğinin yolunu çizmek istiyorum.
Diyelimki bir firmanın araçlarının her çıkışını kaydettiğimiz bir tablomuz olsun. Tablonun şu şekilde olduğunu varsayalım :
Tablo Adı : ARAC_CIKIS_KAYIT
PLAKA KM TARIH
------- ---- ----------
34ABC15 102546 10.04.2012
34ABC15 103542 12.04.2012
34ABC15 110321 17.04.2012
34DD435 101223 08.02.2011
34DD435 110321 15.02.2011
Her çıkışta araçların kaç km. yol katettiklerini bulmak istiyoruz diyelim.
SELECT t.*,
RANK() OVER(PARTITION BY t.plaka ORDER BY t.tarih DESC) ranking
FROM ARAC_CIKIS_KAYIT t;
Yukarıdaki sorguda gördüğüz gibi RANK fonsiyonunu kullanarak yeni bir sütun daha oluşturduk. Bu kodu daha da açıklayayım. OVER() kod parçası yapılacak olan ranking (sıralama,numaralama) işleminin hangi kriterlerde yapılacağının belirtildiği kısımdır. Bu kodda PARTITION BY t.plaka kodu tabloyu PLAKA sütununa göre grupla ve ORDER BY t.tarih DESC kodu ise bu gruplamanın TARIH sütununa göre numaralandırmanın tersten (DESC) yapılması gerektiğini bildirir.
PLAKA KM TARIH RANKING
------- ------ ---------- -------
34ABC15 110321 17.04.2012 1
34ABC15 103542 12.04.2012 2
34ABC15 102546 10.04.2012 3
34DD435 110321 15.02.2011 1
34DD435 101223 08.02.2011 2
Sorgu sonucu görüldüğü gibi kayıtları Plaka alanı bazında gruplandırıp Tarih alanına göre tersten sıralandırmış olduk. Sorgumuzu aşağıdaki şekilde modifiye ediyoruz ve çalıştırıyoruz.
SELECT
*
FROM
(SELECT
t.*,
RANK() OVER(PARTITION BY t.plaka ORDER BY t.tarih DESC)+1 ranking
FROM ARAC_CIKIS_KAYIT t) A,
(SELECT
t.*,
RANK() OVER(PARTITION BY t.plaka ORDER BY t.tarih DESC) ranking
FROM ARAC_CIKIS_KAYIT t) B
WHERE a.plaka=b.plaka
AND a.ranking=b.ranking;
Burada ilk sorgumuzu sanki 2 ayrı tabloya erişir gibi birinin aliası(takma ismi) "A" diğerininki de "B" olacak şekilde ayarlayıp bir tablonun Ranking değerini "1" artırıyoruz. Böylece bir kayıt aslında diğer tabloda kendinden sonraki kayıta eşitleniyor. Sorgu sonucuna bakacak olursak aşağıdaki çıktı kendinden bir sonraki kayıtla eşleşmiş kayıtların listesi şeklinde görüntüleniyor.
PLAKA KM TARIH RANKING PLAKA KM TARIH RANKING
------- ------ ---------- ------- ------- ------ ---------- -------
34ABC15 110321 17.04.2012 2 34ABC15 103542 12.04.2012 2
34ABC15 103542 12.04.2012 3 34ABC15 102546 10.04.2012 3
34DD435 110321 15.02.2011 2 34DD435 101223 08.02.2011 2
Sorgumuzu artık KM alanlarının farkını bulacak şekilde modifiye edebiliriz.
SELECT
a.plaka,
a.km-b.km yapilan_km
FROM
(SELECT
t.*,
RANK() OVER(PARTITION BY t.plaka ORDER BY t.tarih DESC)+1 ranking
FROM ARAC_CIKIS_KAYIT t) A,
(SELECT
t.*,
RANK() OVER(PARTITION BY t.plaka ORDER BY t.tarih DESC) ranking
FROM ARAC_CIKIS_KAYIT t) B
WHERE a.plaka=b.plaka
AND a.ranking=b.ranking;
Sonuç her aracın yolculuk başına kaç km yol katettiğini gösterir
PLAKA YAPILAN_KM
------- ----------
34ABC15 6779
34ABC15 996
34DD435 9098




