SQL'de Group By Yaparak Rapor Oluşturmak
Rapor oluşturmadan önce, birden fazla tablodan veri getirmek ile ilgili farklı bir veritabanından listeleme yapacağız. Daha sonra bu veritabanından getirdiğimiz bilgileri gruplama yaparak bilgilerin rapor oluşturacağız.
Satislar isimli bir ana tablomuz bulunup, bu tablomuzda "hangi bayinin hangi üründen hangi tarihte kaç liradan ne kadar satmıştır" bilgileri yer almaktadır. Sorguda kullanacağımız ana tablo Satislar, yardımcı tablolar ise Bayiler ve Urunler tabloları olacak.
Bu yardımcı tablolardan Bayiler tablosunun yardımcı tablosu Bolgeler tablosu olup, Urunler tablosunun yardımcı tabloları ise UrunCinsleri ve Markalar tablolarıdır.
Bizim burada yardımcı tablo diye adlandırdıklarımız, bir tabloya Foreign Key ile bağlanmış Referans tablolarıdır. Normal anlatım bağlamında ve kavramsal olması için yardımcı tablo terimini kullanıyorum.
Daha önce anlattığım gibi, bir tablo ile yardımcı (referans) tablo arasında ortak bir kolon olması gereklidir. Join yaparken, bu ortak kolon arasında eşitleme yapıp ilişki kuruyoruz. Aşağıdaki Select cümlesindeki Join satırlarında bulunan on teriminden sonraki kısım bu eşitleme yapıp ilişki kurduğumuz kısımdır.
Bir kolon, birden fazla tabloda bulunmuyorsa, veri çekerken bu tablo kolonunun önüne belirteç anlamında bir tablo adı veya tablo takma adı kullanmak zorunda değiliz. Fakat bir kolon, birden fazla tabloda bulunuyorsa ve veri çekerken bu kolon adının önünde tablo adı veya tablo takma adı kullanmak zorundayız. Kullanmazsak hangi tablodaki o isimli kolonu kullanacağını sistem bilemez ve Ambiguous kelimesinin geçtiği bir hata mesajı verir. Tablo adı (veya tablo takma adı) ile kolon adı arasında nokta işareti kullanmamız gerekmektedir.
Aşağıdaki Select cümlesinde Select ile from arasında kullandığımız kolon adlarında bu zorunluluk yoktur. Fakat hangi kolonun hangi tabloda olduğunun belli olması için kolon adlarının önünde tablo kısa adlarını kullandım. Tablo Kısa Adı için Alias terimi kullanılmaktadır.
Daha önceki Select anlatımımızda sözünü etmediğim, gelen listenin sıralanması ile ilgili Order By cümleciğini burada kullandım. Oluşan listenin hangi kolonlara göre sıralanmasını istiyorsam, o kolon adlarını Order By teriminden sonra yan yana yazıyorum. Sıralamanın artan olmasını istiyorsam bu anlamda bir terim yazmasam da liste artan sıralanır. Artan sıralanması anlamındaki terim, kolon isminden sonra kullanılan Asc terimidir. Eğer azalan sıralanmasını istiyorsam, zorunlu olarak kolon adından sonra Desc terimini kullanmalıyım. Asc, artan anlamındaki İngilizce Ascending kelimesinin, Desc ise azalan anlamındaki Descending kelimesinin kısaltılmasıdır.
s.SatisTarihi, bl.BolgeAdi, ba.BayiAdi, uc.UrunCinsiAdi, m.MarkaAdi,
s.SatisFiyati, s.SatisAdedi, s.SatisFiyati * s.SatisAdedi as SatisTutari
from Satislar s
left join Bayiler ba on ba.BayiID = ks.BayiID
left join Bolgeler bl on bl.BolgeID = ba.BolgeID
left join Urunler u on u.UrunID = ks.UrunID
left join UrunCinsleri uc on uc.UrunCinsiID = u.UrunCinsiID
left join Markalar m on m.MarkaID = u.MarkaID
order by SatisTarihi, BolgeAdi, BayiAdi, UrunCinsiAdi, MarkaAdi
Bizim uzun uzadıya yukarıda yazdığımız sorguyu her lazım olduğunda yeniden yazacak olsak, işimiz çok zor olur. Bu sorguya bir isim verip, veritabanında bir View nesnesi oluşturup, o isimli View altında bu sorgumuzu saklayacağız. Sorgumuzun kendisi bu View nesnesinin gövdesidir.
Bir nesne oluştururken Create fiilini kullandığımızı söylemiştik. View de bir nesne olduğundan bu nesneyi de oluştururken bu fiili kullanacağız. Nesne oluştururken Create fiilinden sonra nesnenin türünü belirtiyoruz ve ardından nesneye vereceğimiz ismi yazıyoruz. Bizim nesne türümüzün View olduğunu tahmin etmişsinizdir. View nesnemizin adı SatisBilgileri olsun.
Şimdi bu söylediklerimizi birlikte yazalım: "Create View SatisBilgileri" Bu yazdığımız View nesnesinin başlık kısmıdır. Başlık kısmı ile gövde kısmını arasında bir eklem olarak 'as' bağlacını kullanmaktayız.
s.SatisTarihi, bl.BolgeAdi, ba.BayiAdi, uc.UrunCinsiAdi, m.MarkaAdi,
s.SatisFiyati, s.SatisAdedi, s.SatisFiyati * s.SatisAdedi as SatisTutari
from Satislar s
left join Bayiler ba on ba.BayiID = ks.BayiID
left join Bolgeler bl on bl.BolgeID = ba.BolgeID
left join Urunler u on u.UrunID = ks.UrunID
left join UrunCinsleri uc on uc.UrunCinsiID = u.UrunCinsiID
left join Markalar m on m.MarkaID = u.MarkaID
Bu ifadeyi çalıştırdıktan sonra, veritabanımızın altındaki View nesneleri arasında bu nesneyi görebiliriz. Göremezsek, Refresh yapmamız gerekir. Daha yukarıdaki Select cümlesi ile View nesnesinin gövdesinde kullandığımız Select cümlesi arasında bir fark vardır. O da View nesnesinde Order By cümleciği olmadığıdır. Belli istisnaları dışında View nesnesinde Order By kullanılmaz. Ancak bu View nesnesinden Select yaptığımız zaman Order By kullanabiliriz.
Bu View nesnesini bir tablo gibi kullanıp, bu nesneden istediğimiz sorgulamamızı yapabiliyoruz.
Şimdi de bu View nesnesinden rapor oluşturalım. Rapor ya Group By ya da Pivot kullanılarak oluşturulur. Biz burada Group By kullanacağız. Raporun sol baş kolonlarında gruplarımızı ve sağında da bu grupların Aggregate yani Küme işlemlerinin sonuçlarını elde edeceğiz.
Aşağıdaki gruplamada Satış Tarihini yılına, Bayi Adına ve Ürün Cinsine göre gruplarımızı oluşturmuş olduk. Bu grupların sonunda da, soldaki gruplara bağlı olarak en sağdaki grubun toplamını elde etmiş olduk. Toplamı, Sum fonksiyonuyla hesaplattık.
Sum gibi, Count, Max, Min, Avg isimli küme fonksiyonları da mevcuttur. Bu fonksiyonların sırasıyla anlamları Say, Maksimum, Minimum ve Ortalamadır.
Bu söylediklerimizi içeren gruplamalı Rapor cümlesi aşağıdadır:
Örneğimizi diğer grupların tüm elemanları aynı kalarak, UrünCinsiAdi kolonunda sadece Adel olanları listeleyecek şekilde koşullu hale getirelim: