SQL Server ile En Çok Satış Yapan Personeli Stored Procedure ile Bulmak

 
Aslında bu örneği yaparken, acaba ağır olur mu diye biraz düşündüm. Ama ileri seviye örnekler koymanın da gerektiğini düşündüm. Zira birçok sitede temel seviye örnekler zaten var. Excel'de Pivot tablolarla yaptığımız bir işlemi şimdi burada yapmaya çalışalım. 

Bir satış tablomuz(tblsatis) olduğunu düşünelim, şirketteki personellerin yaptıkları satışlar bu tabloda yer alsın. Ayrıca bir de personel tablomuzun (tblpersonel) olduğunu düşünelim, şirketimizdeki tüm personeller de bilgileriyle bu tabloda yer alsın. Personellerin yaptıkları tüm satışlar MIKTAR olara tblsatis tablosunda yer alıyorsa, personelleri yaptıkları satışlara göre sıralamak istiyoruz. En çok satış yapan personele de ödül vermek istiyoruz. Nasıl yaparız?

tblpersonel Tablosu Yapısı



tblsatis Tablosu Yapısı



tblsatis Tablosu Verileri





Klasik SQL ile en çok satış yapılan Toplam Miktarı aşağıdaki yöntemlerden biriyle bulabilirsiniz.

Yöntem 1:
SELECT TOP (1) MAX(SUM(MIKTAR)) OVER ()
FROM tblsatis
GROUP BY personelID
 
Yöntem 2:
SELECT MAX(t1.SATISTOPLAM)  from  
(SELECT SUM(MIKTAR) AS SATISTOPLAM 
from tblsatis GROUP BY personelID
) AS t1

 
Peki aynı zamanda Satış Miktarı Toplamı  bulup, bu kişiyi Ad ve Soyadı bilgisiyle getirebilir misiniz? Bu işlemi yapmak için bir Stored Procedure yazmak gerekli diye düşündüm, tıpkı bir matematik problemi gibi bu problemin de birden fazla çözümü olabilir.

Aklıma gelen ilk yol döngü içinde tüm personelleri dolaşıp birincil anahtar olan personelID değerine göre tblsatis tablosundan toplam aldırmak. Toplamların içinden de en büyük değeri bulmak için  @maxsatis isminde bir değişken tanımlamak ve  @maxsatis degiskenini kendisinden büyük bir değerle karşılaştığında güncellemek. @maxsatis'i güncellerken o an hangi personelin numarası üzerinde işlem yaptığımızı da @pno değişkeninde tutuyoruz.


CREATE PROC sp_maksimum_satis AS
BEGIN
 
 
DECLARE @max int, @i int, @pno int, @maxpno int;
DECLARE @adi VARCHAR(50), @soyadi VARCHAR(50);
DECLARE @satis decimal(15,2), @maxsatis decimal(15,2);
SET @satis=0;
SET @maxsatis=0;
 
SELECT @max= MAX(personelID) FROM tblpersonel;
SELECT @i= MIN(personelID) FROM tblpersonel;
 
WHILE (@i<=@max)
BEGIN
SELECT @satis=SUM(MIKTAR),@pno=personelID from tblsatis WHERE personelID=@i GROUP BY personelID;
if (@satis>0)
BEGIN
if (@satis> @maxsatis)
BEGIN
SET @maxsatis=@satis;
SET @maxpno= @pno;
 
END
 
END
SET @i=@i+1;
END
 
SELECT @adi=ADI, @soyadi=SOYADI FROM tblpersonel WHERE personelID=@maxpno;
PRINT @adi+' '+ @soyadi+' '+ convert(varchar, @maxsatis);
 
END

Yukarıdaki stored procedure'ü yani Türkçesiyle saklı yordamı aşağıdaki gibi çalıştırabilirsiniz. Sonuç ortada, daha fazla anlatmaya gerek yok. 


 

Çözüm 2:
,
Peki bu problemi hiç Stored Procedure(Saklı Yordam) kullanmadan klasik SQL komutlarıyla çözebilir miyiz? Cevabı aşağıdaki SQL kodlarından inceleyebilirsiniz. Burada TOP 1 ile gelen kayıt kümesinden en üstte gelen bir tanesini alıyoruz, bu komut T-SQL'e özgü bir komuttur. Farklı veritabanlarından TOP yerine farklı komutlar kullanılır. Ardından SQL'deki gruplama fonksiyonlarından SUM fonksiyonu ile MIKTAR alanını topluyoruz ve bunu SATISTOPLAM değişkenine(burada Alias deniyor) atıyoruz. SUM kullandığımız için GROUP BY dedikten sonra nasıl gruplanacağını belirtiyoruz, burada GROUP BY'dan sonra ADI, SOYADI geldiğinine dikkat ediniz. Çünkü dönecek veri kümesindeki personelin ADI ve SOYADI bilgisine göre gruplandırmasını istiyoruz. Sıralamayı büyükten küçüğe yapması için ORDER BY kalıbından sonra SATISTOPLAM DESC kullanıyoruz.  

SELECT TOP 1 p.ADI, p.SOYADI, SUM(s.MIKTAR) AS satistoplam
FROM tblpersonel p, tblsatis s
WHERE s.personelID= p.personelID
GROUP BY p.ADI, p.SOYADI
ORDER BY satistoplam DESC


Yukarıdaki SQL kodunu SQL Server Enterprise Manager içinde çalıştırdığımızda aaşğıdaki sonucu elde ederiz.
 



SQL Server kategorisinden diğer örnekleri görebilirsiniz, yenileri de gelecek. Hergün farklı sorularla karşılaşıyorum, çözüp fırsat buldukça buraya yazmaya çalışıyorum. Aşağıdaki örnekler de ilginizi çekebilir.


MySQL'de Veritabanı ve Tablo Oluşturma
MySQL Veritabanında Parametreli Stored Procedure oluşturma
MySQL Veritabanında Parametresiz Stored Procedure Oluşturma
 

Mutlu kodlamalar,
Oğuzhan TAŞ
Mart, 2018
Bookmark and Share
Dil Değiştir(Change Language)