Gerçekten iyi dizi, ilk bir-iki bölüm oldukça yavan geçiyor. biraz sabır sonrasında Spartacus ve arkadaşları entrikanın dibine vuruyorlar. Ezel’in Roma versiyonu.. hemde gereksiz uzatılmamış :)
1. sezonu tarafımca izlenmiş olup, dizinin “öyle böyle değil” gerçekten çok sert görüntüler içerdiğini söylemek isterim :) İzlenirken dikkatli olunması ve kadınların (özellikle hamile), çocukların izlememesi gerekir diye düşünüyorum.
Bebek odası dediğiniz şeyi hafife almayın, aldırmayın. Yanılırsın “yeğen” der Ramiz dayı. Bebek odasını doğumdan en az 2 ay öncesinde eve gelecek şekilde hazırlıklarınızı yapın. Birkaç kez yıkayın silin tekrar yıkayın silin. Kokusu çıksın diyorlar ama 2 ay boyunca o bebek odasında ne yapacağımızı kimse söylemiyor!
Boya konusuna gelince kendiniz yapmayın, kaşınmayın. Ben kaşındım, kaşıdılar :) Avrupa ve Amerikan filmlerinde çocuk odasını boyayan erken ve romantik erkeklere kanıp evde ben boyarım, ben romantik erkeğim diye geçinmeyin. Aslında o filmlerin yapıldığı ülkelerde işçiliğin maliyeti çok yüksek olduğu için adamın parası yetişmiyor.. sonra yok ben romantiktim de, yok ben kendim boyamak istiyordum da.. inanmayın yaa adamın parası yok.
Paranız var ise profesyonel yardım alın.
Bu arada mobilya alırken gezebildiğiniz kadar gezin. Eli ayağı düzgün mobilyalar için fiyatlar 2000 TL’den başlıyor. Fakat hanıma ve ailenize söz geçirebilirseniz (ama bu çok zor) ucuz bir başlangıç yapın, sonrasında erken yaşta genç odası alın. Emin olun çocuğunuz daha mutlu olacaktır. Anneler ve aileler genelde daha şeker olduğu için bebek odası diye bastırıyorlar.
Mobilya konusunda benim tercihim Masko‘daki Beybish mağazası oldu. Yani isminden de anlaşılacağı gibi ben bebek odası aldım.. :) Ehh yazıyoruz ama yazdığımızı yapıyoruz anlamına gelmiyor elbette.
Oldukça yakın ve kadim dostlarımdan Litespell yöneticleri, Litespell bünyesinde bir yazılım ekibi oluşturma çabasına girişti. Oldukça güzel, neşeli bir çalışma ortamda İnternet teknolojilerinin mutfağında çalışmak isteyen arkadaşlar başvurularınızı bekliyoruz.
Genel ağ üzerinde öyle deli divane gezerken gördüm, paylaşmak istedim bu çok iyi yazıyı.
Çoklu dil desteği olan (Örneğin İngilizce, Türkçe, Almanca..vb.) yazılımları geliştiren arkadaşların kontrol etmesi gerekenleri çok güzel bir şekilde listelemiş, sorunları anlatmış, çözümlerini vermiş. Örnekler .NET (C#) üzerinden ama bu ayrıntıya takılmayalım önemli olan problemleri size hatırlatması ve çözüm bulması.
Bu aralar evde ve iş yerinde oldukça yoğun ve yorucu bir dönem geçiriyorum. Özellikle Vodafone’da oldukça sert bir dönemi geride bıraktık ama başarı ile bıraktık :) yani en azından teşekkür maili aldık, bizi bu kadar yoran şey ise Vodafone’un yeni özelliği “Tek Fatura” (Single Invoice), işin büyük kısmı Fatura üzerinde olduğu için canımız çıktı diyebiliriz, ama başarının verdiği o güzel hazzı, projenin son gününden 1-2 gün önce tatmayı başardık. Üstelik Vodafone IT departmanı 2 sene sürmesi planlanan bir değişim sürecine girdiği şu sancılı günlerde yaptık bunu :) kolay iş değil yani…. Yoğunluk diyorum, diyorum ama aklınızda soru işareti oluşmasın, tüm bu çalışma boyunca (6~7 yıldır olduğu gibi) ben hiç fazla mesai yapmadım, çalışma arkadaşlarımdan Salih Diler ise, sadece birkaç gün fazla mesai yaptı.
Hayatımdaki yoğunluğun Vodafone kısmı bu şekilde devam ederken, dertsiz başıma bir de yeni televizyon alma derdini eklendim, sanki sizleri duydum “iyi halt ettin” mi dediniz ? Eh teknoloji ile ilgileniyoruz yaa, bu işlerden anlıyoruz yaa.. öyle gözümüzü kapatıp “aaaa bu televizyon güzelmiş, hemen alalım şunu” diyemedik, 2 hafta boyunca girmediğim site, okumadığım yazı, bakmadığım özellik açıklaması kalmadı, üzerine bir de işin felsefesine kaçtık, fiyat performans çıkartırken mantık çercevesinde her bir özelliğin ne kadar edeceğini bulmaya çalışıp, bu özelliklerin fiyatları ne kadar etkilediklerine baktım, inceledim.. falan filan.. uzun uzun yazmadan hemen sonunu söyleyeyim, gözümü kapadım ve Sony Bravia aldım… aldıktan sonra “bu işi baştan yapsaydım” dedim :)
Öncelikle birşeyi belirtmek zorundayım, şu plazma ve lcd tartışmaları artık gözümde son buldu. Şöyleki tüm özellikler artık birbirlerine denk gibi, fakat en ayırt edici özellik LCD’lerin daha az elektrik yakması (Çevreye duyarlı bir vatandaş olarak bu benim için çok önemli) ve yüksek çözünürlüğe sahip olmaları. Özellikle LCD’lerdeki parlaklık sorunuda çözüldükten sonra (Kontrast Oranı 5000:1′den düşük almayın, hatta yanına yaklaşmayın, tersini söyleyen kişiye inanmayın) LCD, plazmanın önüne geçti. Özellikle son teknoloji LED LCD’ler ve 100 Hz’lik LCD’ler tam bir sanat eseri. Cebinizde 10.000 YTL’niz var ise Samsung’un bir modeli var.. kaçırmayın derim, benim yoktu kaçırdım bir dahaki bahara artık.
İşin felsefi tarafını özetlemek gerekir ise, bir televizyona 3000 YTL’den fazla verilmez. Bu tarihte (Kasım 2007′de) Full HD almanın bir anlamı yok Blue-Ray veya HD-DVD sistemlerinin yaygınlaşması gerekiyor. Fakat 1080i girişi destekleyen bir model almalısınız.
Ek bir bilgi olarak http://www.istanbulbilisim.com.tr adresinden modellerin detaylı bilgileri bakabilirsiniz, fiyat olacak pek cazip bir site olmasada, diğerlerinden daha fazla model ve özellik açıklamaları bulabilirsiniz.
Bir de Amerika’da birkaç arkadaş var ki, bu aralar canımıza okuyorlar :) Ahh şu Stanford’lu gençler yok mu…
Uzun süredir herhangi bir yazı yazmıyordum, arkadaşlar arasında konuşurken “neden yazmıyorsun” gibi sorulara maruz kaldım, “eee dedim yazacak pek bir şey kalmadıki, ben ruby veya yazılım ile ilgili konularda yazıyorum” dedim. “eğer herhangi bir konuda istek gelir ise o konuda yazarım ama, şimdilik böyle bir konu yok” dedim. Dedim de hemen cevabı yapıştırdılar suratımın orta yerine.. “Ruby dizileri gerçekten basit tutmuş, herhalde hız için.. Lisp veya fonksiyonel programlama dileri kadar esnek değil” dediler.. “Eneee” dedim :) bana yazı yazacak konu çıktı.
Şimdi öncelikle biraz konu ile ilgili kendimizi motive edelim; Neden dizi işlemleri bu kadar önemli ? Ya da diğer işlerden farkı ne olabilir ki ?
Öncelikle bir konuya açıklık getirmek gerekir, günümüzde yazılan programlar içerisinde pek çok durumda dinamik veya durağan veri kümeleri ile işlemler yapılıyor. Bu işlemler, yazdığımız programlar içerisinde performansı etkileyen en önemli etken olarak karşımıza çıkıyor. Ve günümüzdeki daha fazla veri üzerinden daha doğru bilgi edinme anlayışı nedeni ile dizilerin boyutları gün geçtikce artıyor ve üzerlerinde yapılan işlemler gün geçtik fazlalaşıyor, bu performans etkeni daha da önemli hale geliyor. Yanlış anlaşılma olmasın, burada bahsettiğim performans Şişirme Veri Girişi adlı yazıda bahsettiğim veri yoğunluğunun artması ile beraber ortaya çıkan performans kötüleşmesi.
Diziler üzerinde yapılacak işlemlerde öncelikle iki ana başlıkta değerlendirilmelidir;
1- Kolay kullanım,
2- En iyi algoritmanın kullanılması.
İkinci maddenin neden gerekli olduğu konusunda fazla söze gerek yok ama, birinci maddenin neden gerekli olduğu konusunda aklınızda sorular olabilir, bu soruları ortadan kaldırmak için şu şekilde bir açıklama yapabilirim. “Diziler üzerinde yaptığınız optimizasyonlar, algoritma seçimleri veya memory optimizasyonları” gerçekten zor ve uygulanması oldukça tartışmalı olabilir. Örneğin google’ın java dili için çıkardığı “Google Collections Library” buna örnek olarak gösterilebilir. Kolay kullanım ve entegrasyon yazılımcılar tarafından her zaman tercih edilir.
Peki Ruby tüm bunların karşısında bize güzel silahlar veriyor. Aslında tüm Ruby işlemlerinde olduğu gibi performans basitliğin gerisinde kalmış, yüzlerce kez söylediğim gibi “yazılımın çalışma hızı sonsuza giderken, geliştirme süresi sıfıra gitmeli” felsefesine ters değil.
data = [1,2,4,8,12,5,7,3,0,13,10,11,3]
# For..In
data.each { |x| puts "x=#{x}" }
# data içerisindeki tüm elemanları tek tek verilen
# blok içerisindeki işlemden geçirir ve sonuçlardan yeni bir dizi üretir.
puts data.collect { |x| x + x }
# For..In :) ile indexleri verir.. :) pek çok programlama dilinde
# karşılığı bulunmaz.
data.each_with_index { |x, index| puts "#{index}. eleman = #{x}" }
# 5'den büyük ilk kayıdı bulur.
puts data.detect { |x| x > 5 }
# 5'den küçük olanları true_data değişkenine,
# diğerlerini false_data değişkenine dizi olarak atar.
true_data, false_data = data.partition { |x| x < 5 }
puts true_data
puts false_data
# 5'den küçük olanları diziden çıkartır ve geri döner.
puts data.reject { |x| x < 5 }
# Varsayılan sıralama işlemi
puts data.sort
# Belirlenmiş kritere göre sıralama işlemi (string olarak sıralama)
puts data.sort_by { |x| x.to_s }
# veya
puts data.sort_by { |x| (x+5)/x }
Türkiye’nin ilk ‘ticari’ RoR (Ruby on Rails) uygulamalarından birisi olan Kizlarayaklandi yarışması sonuçlandı. Büyük ödülü kazanan Burcu Güleç‘i ve diğer kazanan arkadaşları başarılarından dolayı tebrik ederim. Projede emeği geçmiş olan herkeze, özellikle Litespell’den Erhan Yürük ve Mehmet Hazman’a teşekkür ederim. Beraber nice güzel projelere diyorum ve bitiriyorum :)
Uzun süredir böyle güzel bir film seyretmemiştim. İlk 10~20 dk. içerisinde tempo biraz düşük eğer yılmaz ve filmin devamını izlerseniz yaşattığı duygu seli sizleri oldukça tatmin ediyor.
Öncelikle bu duygu selini yutmak, hazmetmek istiyorsunuz. Ama size fazla geliyor, kendinizi çok zorluyorsunuz görünürde 5 yaşındayken 2 külah dondurmanın size yaptığı etkiyi yapıyor, midenize oturuyor, tam tanımı “Boğazınızda birşeylerin eksikliğini hissettiren bir yumru ve midede hafif bir kasılma”.
Bu film ne 2 külah dondurma, ne de bizler 5 yaşındayız.
Bugün yeni gelen bilgisayar masamın şerefine bir yazı yazmak istiyordum ama öyle boşu boşuna yazı yazamayacağım için arada sizlere regular expression’dan bahsetmek istiyorum :)
Öncelikle sizlerin de yazılım hayatınıza başlayalı 5~10 yılı geçtiyse artık etraf koddan geçilmez hale gelir. Her yerde başka kodlar, hepsinize siz yazmışsınızdır ama.. “kardeşim ne yazmışım yaa, bu kadar da olmaz ki”.. dersiniz. Daha sonrasında kendinizi birşeyler araken ve en önemlisi bulumazken bulacaksınız.. “ahh nereye koymuştum bunu salak şeyi..” dersiniz.. tekrar dersiniz.. ama bunu söylemenin bir etkisi yoktur, gene bulamazsınız.. gene bulamazsınız.
Ya da size bir iş verirler. RegEx (Regular Expression) kullanmanız gerekir.. Gerekir gerekir gerekmez demeyin. Örnek vermek gerekir ise, geçen gün Zodazone Türkiye’de belirli bir tabloda yer alan açıklama bilgilerini değiştirilmesi istendi üstlerden bir yerlerden (ne biliyim muhasebeden falan işte..).
Bize bir ofis dökümanı içerisinde tekil kod bilgisini ve yanında yeni açıklamasını gönderdiler.. Onlar oturmuş kasmış… hatta uğraşmış sabahlara kadar 150 civarındaki açıklamayı kafa patlatmışlar, düşünmüşler, taşınmışlar.. ve değiştirmişler.. Tabii ne zennetiniz sadece bunun için maaş alan adamlar bile mevcut.
Ehh tabii bu Tankut kardeşiniz oturup, 150 tane açıklama alanını tek tek yapacak hali yok. Deli miyim ben :) söz meclisten dışarı efenim :) Neyse şimdi bu dökümanı gönderdiler ya içerisinde sadece açıklama bilgisi bulunmuyor ki, kim bilir hangi düzenle yazdılar bu dökümanı diye bir düşünün bakalım.. Regular Expression olmadan adım atamazsın adım….
Neyse öncelikle güzel güzel açıklayalım bu RegEx nedir, ne değildir ?
RegEx, karakter yığınları içerisinde özel belirtilen karakter veya karakter kümelerini bulmak, diğerlerinden ayırmak için kullanılan oldukça gelişmiş bir kütüphanedir. Kullanımı biraz zordur, hemen kısa sürede alışmanız zor olabilir.
Öncelikle RegEx tanımlarını ve anahtar kelimelerini tanıyalım; (Kitap yazmıyoruz burada ona göre.. tüm özelliklerini yazmıyorum sadece çok kullandıklarımı)
Anahtar kelimeler: ^ : Satır başını ifade eder. \n : Enter karakteri için kullanılır. \t : Tab karakteri için kullanılır [...] : Örnek: [aeıioöuü] sadece sesli harfleri bulunur. ‘[]‘ karakterleri içerisinde yer alan herhangi bir karaktere uyanları getirir. [^...] : Örnek: [^aeıioöuü] sadece sessiz harfleri bulunur. ‘[^]‘ karakterleri içerisinde yer alan herhangi bir karaktere uymayanları getirir. . : Yeni satır (\n) karakteri hariç herhangi bir karakteri ifade eder. Tek karakteri \w : Herhangi bir alfanumeric veya numeric karakteri işaret eder. a..z, A..Z, 0..9 \W : \w’nin tersidir. \d : \d herhangi numeric karakter. \D : \d’nin tersi. \ : bir sonraki karakter özel bir anlam ifade ediyorsa, bu özelliği iptal eder.
Destekleyiciler ? : Bir önceki karakterden bir tane var ise bulur. + : Bir önceki karakterden bir ve birden fazla var ise. * : Bir önceki karakterden 0 ve birden fazla var ise. {n} : Bir önceki karakterden n adet olanları bulur. (…) : Gruplama işlemi yapar. ‘()’ içerisine yazılanlar grup olarak değerlendirilir. | : ‘OR’ işlemi için kullanılır, 2 farklı RegEx bu şekilde bağlanabilir.
Opsiyonlar: i : Büyük küçük harfe duyarlı olmaz. m : Karakter katarını birden çok satırmış gibi düşünür. s : Karakter katarını tek satırmış gibi düşünür.
Geçmiş zaman olurki bir proje için internette yayınlanan videoların kaç kez görüntülendiğini öğrenmek isteyen arkadaşlar ile tanıştım, çok ısrar ettiler yaptım. Bazı siteler için süper basit ve hızlı olurken bazıları için uzun sürdü ama 5 site için görüntüleme bilgilerini 2 saat gibi uzun bir sürede yapmayı başardım. Öff bee çok uzun sürmüş harbiden… şimdi yazınca daha da uzun geldi… aman aman bir daha yapmam valla… bu nedenle sizler de tekrar tekrar uğraşmayın diye bu Tankut kulunuz bu yazıyı yazıyor. Sırf sizler için, reklamları tıklamanız için değil, adımı ağzınızda sakız yapmanız için değil.. sadece siz uğraşmayın diye.. heyttt bee hizmet etmeye geldik diye siyasi bir yaklaşım içerisinde bulunan ve hiç birşey yapmayanlar utansın..
Öfff öff gene gereksiz yazdım işte örnekler :)
Öncelikle bulduğumuz gösterim sayılarını (view count) html veya “,” gibi karakterler ayırmak için bir methoda ihtiyacımız var. İşte ‘remove_char’ methodu tam bu noktada isteklerimizi karşılıyor.
def remove_char(number)
ret = ''
number.to_s.split(//).each do |char|
ret += char if char.to_i.to_s == char
end
ret
end
Öncelik google kardeşimizin olsun, google kardeşimiz video url’i aslında frame’lerden oluşuyor. Ve gösterim sayısının (video view count) bulunduğu frame’i üstün araştırmalarımın sonucunda buldum… :) url’de ‘videoplay’ yerine ‘videohosted’ yazıyorsunuz oldu bitti maşallah :).
Öncelikle karşılaştırma derken, nasıl bir karşılaştırma yapacağımızı anlatmalıyım. Performans işlemleri karşılaştırma kriterlerim içerisinde bulunmuyor, bundan hiç bahsetmeyeceğim. Ama kodun okunabilirliği, hızlı yazılması, hatalara karşı ne kadar duyarlı olduğu ve tabii ki en önemlisi tekrar kullanabilirliği.
Aslında bu son nokta yani ‘tekrar kullanılabilirlik’ başlı başına bir yazı konusu ama buna şimdilik pek değinmeyeceğim. Başlıkta yazdığı gibi dosya işlemlerini karşılaştıracağım.
Arşılaştırmayı sadece VBScript, JScript ve Ruby arasında yapacağım, neden mi ? hali hazırda yapmıştım da ondan.. bu yazıyı yazacağım diye oturup program yazmadım. Önce programları yazdım, sonra yazıyı yazmak aklıma geldi. Bu nedenle neden diye sormayın. :)
Ama belki daha sonraki zamanlarda Java ve C# versiyonlarının karşılaştırmalarını da eklerim.
Öncelikle sizlere problemden bahsedeyim.
Belirli bir server üzerinde ps ve txt (post script ve text) dosyaları online bir uygulama tarafından oluşturuluyor, daha sonrasında online uygulama üzerinden kullanıcı bu dosyaları temizlemeyi unutuyor ve dosya sisteminin şişmesi ile beraber performans problemleri ortaya çıkıyor. Bu nedenle dosyaların gün bazında ömürlerinin olmasına ve ömrünü doldurmuş olan dosyalarında sistem tarafından silinmesine, silme işlemi esnasında log almasını ve bu loglarında aynı ömür kuralına tabii olmasını istiyoruz… işte bu program bu işi yapacak.. günde bir kez çalışacak ve bu işlemi yapacak. Microsoft Windows sistemde çalışmasını istediğimiz için VBScript ve JScript’de (JavaScript’in bire bir aynı klonu) ve platform bağımsız olan Ruby’de yazıldı. İşte Ruby örneği; Read the rest of this entry »
Bu yazımı aslında takip ettiğim bir kaç sitede yayınlanan blogları gördükten sonra yazma gereği duydum. Bahsettiğim bloglarda yer alan yazılar aslında basit anlamda Ruby’nin temel özelliklerinden bahsediyorlarda fakat bu yazılara çok farklı tepkiler geldi. Bu tepkiler içerisinde çok şaşıranlar.. hadi ya ben bunu bilmiyordum diyenler.. yaa demek böyle birşey varmış ama bu kötü vs..vs.. Ben de bu yorumları inceledikten sonra bu yazıyı yazmaya karar verdim.
Aslında konumuz Ruby’de sınıfların yapısı, özellikleri ile Ruby’nin sınıfları, kütüphaneleri ve bizim Component dediğimiz şeyleri nasıl gördüğüdür.
Öncelikle OO (Object Oriented) tüm dillerde olduğu gibi Ruby’nin sınıf tanımı Java’nın veya C#’ın sınıf tanımı ile aynıdır. Peki o zaman farklılık nerede :) ayrıntılarda.. şeytanın gizli olduğu yerde :)
public class HelloWorld extends ExampleSupport {
private String execute() throws Exception {
setMessage(getText(MESSAGE));
return SUCCESS;
}
}
Yukarıda belirtilen örnekte olduğu gibi execute isimli methodumuz private tanımlanmış, yani sadece HelloWorld sınıfı içerisinden kullanılabilir. Neden çünkü private…
peki bir de bunun benzerini Ruby’de gerçekleştirelim;
class HelloWorld < ActiveSupport
private
def execute
SetMessage(GetText(MESSAGE))
return SUCCESS;
end
end
Yukarıdaki iki örnek birbirlerinin aynısı. Ama diyorum ya şeytan bu ayrıntılarda gizli elbetteki.. :) Tahmin ettiğiniz gibi Java dilinde herhangi bir esneklik yok tabiki.. private tanımladın.. private.. yok öyle yanar döner method tanımlama olayları...
Peki ya Ruby'de private olarak tanımlanmış bir methodu public yapabilirmiyiz.. elbette yaparsınız; private yerine public yazarsınız.. taaa taa oldu.. :) Diğer bir yöntem;
Parçalı sınıf (Partial Class) yönetimi ile yapılabilir.
class HelloWorld
public
def execute_public
execute
end
end
peki başka nasıl olur bu iş.. mesajlaşma ile olur.. şöyleki aslında bir methodu çağırmanın tek yöntemi o methodu direkt olarak çağırmak değildir. Ayrıca Reflection dediğimiz kavram ile de çağrılabilir (Java dünyasında da oldukça kullanılır).
helloWorld = HelloWorld.new
helloWorld.execute # Hata üretir.. execute halen private bir methodtur...
helloWorld.execute_public # Çalışır :)
helloWorld.send("execute") # Çalışır.. problem çıkarmaz.. Sınıfa execute adlı bir method çalıştırmasını söyler.
helloWorld.instance_eval("execute") # Çalışır.. problem çıkarmaz..
Görüldüğü gibi.. yazılımcıdır tüm kodların hakimi.. yoktur programlama dilinin mecburiyetleri.. :P
En son olarak benim tercih ettiğim yöntem; tabii private yerine public yazmak yerine.. :)
class HelloWorld
public :execute
end
Yukarıda belirtilen bu yordam ile.. execute methodu artık public olmuştur.. hayırlı uğurlu olsun.. :D
Tatile çıkamayanları düşündükçe bu yazıyı yazmak içimden gelmiyor ama :) BEN TATİLE ÇIKIYORUM :) diye bağırıyorum :) işte gördünüz bağırdım. Uzun uğraşlar sonucunda, Vodafone’da bulunan sevgili yönetici kardeşlerimizin benim 3 hafta olan tatilimin hepsini kesmemeleri konusunda ikna edebildim ve 3 hafta çıkmam gereken tatilime 1 haftacık da olsa çıkabileceğim için ne kadar mutluyum bilemezsiniz. Bana bu hazzı yaşatan sevgili yöneticilerime teşekkürü bir borç bilirim. Üstelik bana ‘sen daha yeni geldin ya, ne tatili ?’ diye soran çalışma arkadaşlarımı da sizlerin huzurunda sevgiyle kucaklıyor :) ve ben TATİLE ÇIKIYORUM :)
Kendinize iyi bakınız, bir aksilik çıkmaz ise, sizlere Bodrum’dan da bir yazı yazmaya çalışacağım. Hoşçakalın.
Bu yazı, bir önceki SQL nedir, ne değildir ? adlı yazının devamı şeklinde olacak ve ‘Group By’ ve ‘Having’ ile SELECT sonuçu olarak dönen liste üzerinde yapılan işlemlere değineceğiz.
Geçen yazımızdan hatırlayacağınız gibi, SELECT cümlesi geriye bir liste dönen bir ve üç ana parçaya ayırabileceğimiz bir komut idi. Bu ana parçalardan kısaca bahsedecek olursak;
- süzme işlemi (WHERE alt cümlesi ile yapılabilen)
- sıralama işlemi (ORDER BY alt cümlesi ile yapılabilen)
- geri dönen liste üzerinde yapılan işlemler (GROUP BY, HAVING, MAX, SUM, COUNT, MIN….vs.)
Peki SELECT cümlesinde gerçekleşen olayları biraz daha derinden inceleyelim, bu şekilde GROUP BY ve diğer işlemlerin anlaşılmasını kolaylaştırmaya çalışalım.
SELECT Price
FROM Customer
WHERE Price < 100
AND Price > 50
Bu SQL cümlesinden geriye bir liste gelir, buraya kadar herşey çok normal ve oldukça basit. Ama biz biraz daha analitik bir liste istersek ki iş dünyasında bu çeşit listelere oldukça fazla başvuruluyor.
SELECT Count(*), Price
FROM Customer
WHERE Price < 100
AND Price > 50
GROUP BY Price
Yukarıdaki cümlede durum biraz karışık ama inanın göründüğü kadar değil, şöyleki; Bu SELECT cümlesi bir üstte belirtiğimiz SELECT cümlesi ile aynı listeyi oluşturur ama son yazılan SELECT cümlesine ‘Count(*)’ ve ‘GRUOP BY’ gibi SELECT’den dönen listeyi değiştiren alt cümleleri eklenmiştir. Biz standart listeleme işleminden dönen (yani Price bilgisi 100 ile 50 arasında olan Customer listesine) listeye düşük seviyeli liste diyelim. Bu düşük seviyeli listenin üzerine GRUOP BY ve COUNT işlemleri uygulandıktan sonra ortaya çıkan yeni listeye ise sonuç listesi adını verelim.
Veri tabanı uygulamaları, işte bu mantık doğrultusunda öncelikle düşük seviyeli listeleri oluşturur ve bu düşük seviyeli listeler üzerine yapılan işlemlerle sonuç listesini meydana getirirler. Bu bilgiler ışığında GROUP BY alt cümlesinin tanımı şu şekilde olabilir;
- Cümleden sonra parametre olarak belirtilen alanın veya alanların değerine göre düşük seviyeli listeyi parçalara ayırır, belirtilen alanın veya alanların kaç farklı değeri var ise o kadar düşük seviyeli liste oluşturur.
Bu tanım biraz daha aklınıza yattı değil mi.. ?
Peki şimdi bir de COUNT(*), MIN, MAX, AVERAGE gibi fonksiyonların nasıl çalıştıklarını anlatmaya çalışalım;
- Tüm bu fonksiyonlar, düşük seviyeli listenin tamamı üzerine çalışır. Eğer düşük seviyeli liste GRUOP BY ile bölünmüş ise, her bir parça için ayrı ayrı çalışırlar.
Yani son SQL cümlesinde yer alan Count(*) işlemi her Price değeri için bölünmüş olan düşük seviyeli listenin herbir parçası için çalışır. Ve ortaya sonuç listesi olarak, her parçanın içerisinde yer alan kayıt sayısı ve her parçanın ayıraçı konumundaki Price bilgisi çıkar. Örnek;
Count(*) - Price
5 60
7 70
... vb.
Peki biz şu şekilde bir SQL cümlesi yazacak olursak;
SELECT Count(*), Price, Name
FROM Customer
WHERE Price < 100
AND Price > 50
GROUP BY Price
Veri tabanı bize hata verecektir. Hemen aklınızdan ‘Kardeşimmmm bu ne hatası böyleee…. eee Customer üzerinde Name var.. neden görmez bunu bu salak..’ vb. düşünceler geçebilir. Aman geçmesin çünkü veri tabanı manyağı haklı. Peki neden haklı onu inceleyelim;
Şimdi öncelikle düşük seviyeli listenin ne olduğunu bulalım;
- Price bilgisi 100 ile 50 arasında olan Customer bilgileri.. Id, Price, Name…vs.. vs.. Bu listeye ‘A’ listesi diyelim.
‘GRUOP BY’ işlemi olduğuna göre, elimizdeki düşük seviyeli ‘A’ listesi Price bilgisinin değerlerine göre bölümlere ayrılmıştır. Örnek olarak Price bilgisi 5 farklı değere sahip olsun elimizdeki ‘A’ listesi ‘A1, A2, A3, A4, A5′ şeklinde küçük listelere ayrılır.
Daha sonra COUNT(*) işlemi ile bu her bir küçük listenin adet bilgisi ile Price ve Name bilgisi sonuç listesine verilmiştir. Peki burada ki gariplik ne, neden hata veriyor. Sorun şu A listesinden A1′e geçiş sırasında her bir Price’a karşılık ‘n’ adet Name bilgisi oluşmuştur bu nedenle sonuç listesi oluşturulurken, Count bilgisi hesaplanmış, Price bilgisi tek olduğu için alınmış fakat hangi Name bilgisinin kullanılacağına karar verilememiştir.
Düşük Seviyeli Liste’nin son hali..
Id
Price
Name
1
60
Test60-1
2
60
Test60-2
3
70
Test70-1
4
70
Test70-2
5
80
Test80-1
6
90
Test90-1
‘Group By’ uygulandıktan sonraki düşük seviyeli listenin hali;
Price
Alt Kümeler
60
Id
Name
1
Test60-1
2
Test60-2
70
Id
Name
1
Test70-1
2
Test70-2
80
Id
Name
1
Test80-1
90
Id
Name
1
Test90-1
İşte bu da son ipucu; SQL programlama dilinde herhangi bir liste oluşturabilmek için bir kademe altta yer alan listenin elemanları direkt olarak kullanılabilir ya da fonksiyonlar yardımı ile alt listelere ulaşılıp, toplam, en küçük, en büyük, ortalama.. vb. değerler elde edilebilir.