standart sapma ile ilgili UDF yazamadım

Firebird ve Interbase veritabanları ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
Kullanıcı avatarı
comfort
Üye
Mesajlar: 214
Kayıt: 28 Ara 2004 06:37
Konum: İzmir
İletişim:

standart sapma ile ilgili UDF yazamadım

Mesaj gönderen comfort »

Herkese ii çalışmalar. Formu baya aradım ama soruma yanıt bulamayınca sormaya karar verdim.

Kod: Tümünü seç

select avg(puan) from puantablosu;
Bu kodla ortalamayı çok kolay bir şekilde alabiliyoruz. Peki ya standart sapmayı bulabilmek için ne yapmalıyız. Ben şöyle bir UDF yazmaya çalıştım beceremedim :wink:

Kod: Tümünü seç

select stddev(puan) from puantablosu;
DLL dosyasıda şu şekilde

Kod: Tümünü seç

unit Unit1;
interface
uses
math;
 function standart_sapma(seri:array of double):extended;cdecl;export;
implementation
function standart_sapma(seri:array of double):extended;
begin
  result:=StdDev(seri);
end;

end.
dpr dosyasının içeriği

Kod: Tümünü seç

library udf_stddev;

uses
  Unit1 in 'Unit1.pas';


{$R *.res}
exports standart_sapma;
begin
end.
sorgudan dönen her kaydı DLL de tanımladığım diziye sırayla atabilirsem sorunum çözülür gibi geliyor bana.
poshet303
Üye
Mesajlar: 235
Kayıt: 26 Eki 2005 01:15

Mesaj gönderen poshet303 »

Merhaba;

Pek çok sql sunucusunda (Oracle), hatta eski veritabanı yönetim sistemi yazılımlarında (DBase) temel itatistik fonksiyonları var.

Şimdiye kadar ihtiyacım olmamıştı. Fakar firebird te temel istatistiksel fonksiyonların bulunduğunu tahmin ederdim. Vesileniz ile bunun böyle olmadığı öğrendim.

UDF ile standart sapma hesabı bana pek olanaklı gelmiyor. Sizinde belirttiğiniz gibi belli bir alanın tüm eğerlerini UDF e geçirmek pek olası değil. Bellek yönetimi çok zor olur böyle bir durumda.
Firebird UDf kütüphanelerini araştırdım standart sapma yada varyans hesaplayan bir örnek bulamadım.

Aslında UDF e gerek yok. Bu hesap başka türlüde yapılabilir.

Ben önce daha genel bir form yakalamak için Stored Procedure kullanmayı düşündüm ama tablo ve alan ismini parametre olarak geçirmedikçe genel bir form elde etmek mümkün olmadı.

O zaman ne yapacaz. Size küçük bir örnek gösterdiğimde beyninizde bir ışık yanacaktır. Ama sorunlar bitmedi. Önce örnek.

sarfhareket adında bir tablomuz var. Alisfiyati ise varyansını hesaplayacağımız alan (field). AlisfiyatiVaryansi sonucu atayacağımız alias field. Where kısmı önemli değil. Benim için gerekliydi yazdım.

Kodumuz şöyle. Burda yaptığımız şey basit. Sadece Varyansın hesaplama formülünü kullandık.

Kod: Tümünü seç

Select (SUM(ALISFIYATI*ALISFIYATI)-(AVG(ALISFIYATI)*AVG(ALISFIYATI)*Count(ALISFIYATI)))/(Count(ALISFIYATI)-1) AS AlisfiyatiVaryansi from sarfhareket
 Where (ALISFIYATI is not null) and (ALISFIYATI>0)
Sorun ne mi? Efendim bu Alisfiyati alanımız 2 haneli ondalığa sahip bir NUMERIC alan. Buna rağmen yukarıdaki script çalıştırılınca FIREBIRD ondalık sayıları ihmal ediyor. Bu nedenlede yaklaşık bir VARYANS değeri elde ediyoruz. Pek çok örnekte bu yaklaşık değer işimizi görmeyecektir. Ve hatta bazı örneklemlerde VARYANS negatif çıkabilir (ki bu tanım gereği imkansiz aslında)

Firebird ün bu konuda zorluk çıkarması beni gücendirdi doğrusu. Firebird ten daha iyi bir iş çıkarmasını beklerdim. Fakat belki bu sorunu çözebilecek bir arkadaşımız çıkabilir.

Kolay gelsin.
Kullanıcı avatarı
comfort
Üye
Mesajlar: 214
Kayıt: 28 Ara 2004 06:37
Konum: İzmir
İletişim:

Mesaj gönderen comfort »

Cevabınız için teşekkür ederim. Dediğiniz gibi SP içinde yapabilirim bunu hatta önceden aklıma gelmişti. Ama avg fonksiyonu gibi std.sapma fonksiyonu neden yok fb de anlamadım. Neyse zaten yakında oracle a geçcem böyle sorunları oracle da yaşamıycağıma eminim :P Kolay gelsin
Kullanıcı avatarı
comfort
Üye
Mesajlar: 214
Kayıt: 28 Ara 2004 06:37
Konum: İzmir
İletişim:

Mesaj gönderen comfort »

Delphideki stddev fonksiyonunun yanlış olma ihtimali varmıdır. Çünkü benim hesapladığım standart sapma sonucu bu fonksiyonunkiyle tutmuyor. Diyceksiniz sen yanlış hesaplıyon. Kalem kağıtla teker teker hesapladım. Benim sonuç kesin doğru. 8)
Cevapla