Hesaplanan alan değerini tekrar hesaplamadan kullanmak

MS SQL Server veritabanı ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Hesaplanan alan değerini tekrar hesaplamadan kullanmak

Mesaj gönderen sabanakman »

İyi çalışmalar;
Bir sorguda alt sorgu kullanarak bir hesaplama yaparak gösterdiğimiz alan değerini tekrar hesaplatmadan göstermenin bir yolu var mıdır? Soru açık değil en iyi örnekle anlatabilirim. Bir öğrenci tablosu ve devam tablosu olsun. Burada şöyle bir sorgu ile devamsızlık rapor edilebilir.

Kod: Tümünü seç

select ogr.No, ogr.Adi, ogr.Soyadi, 
(select sum(dvm.Devam) from Devam as Dvm where Dvm.No=Ogr.No and dvm.Tur='D') as 'Devam Etmediği Gün', 
(select sum(dvm.Devam) from Devam as Dvm where Dvm.No=Ogr.No and dvm.Tur='R') as 'Raporlu Olduğu Gün'
from Ogrenci as ogr
gibi bir sorgunun şuna benzer bir çıktı vereceğini düşünelim.

Kod: Tümünü seç

No   | Adi       |Soyadi     |Devam Etmediği Gün  |Raporlu Olduğu Gün
-----|-----------|-----------|--------------------|------------------------
   1 | Murat     | Gezer     |                  3 |                      0
   2 | Ali       | Çolak     |                  2 |                      2
Şimdi bu durumda şöyle bir alana daha ihtiyaç duyulduğunu farzedelim. "Mazeretsiz Devamsızlık" Bunun da formülü Devamsızlık-RaporluGün olsun. Bunu karşılayacak sorguyu nasıl yazarım? Burada ilk gelecek cevabı ben şimdiden kendime göre yazayım.

Kod: Tümünü seç

select ogr.No, ogr.Adi, ogr.Soyadi, 
(select sum(dvm.Devam) from Devam as Dvm where Dvm.No=Ogr.No and dvm.Tur='D') as 'Devam Etmediği Gün', 
(select sum(dvm.Devam) from Devam as Dvm where Dvm.No=Ogr.No and dvm.Tur='R') as 'Raporlu Olduğu Gün',
----------------------------------------------------------------
(select sum(dvm.Devam) from Devam as Dvm where Dvm.No=Ogr.No and dvm.Tur='D')-(select sum(dvm.Devam) from Devam as Dvm where Dvm.No=Ogr.No and dvm.Tur='R') as 'Mazeretsiz Devamsızlık'
--------------------------------
from Ogrenci as ogr
Şeklinde bir cevap gelecektir. Benim asıl sormak istediğim bunun A-B gibi pratik bir formülü var mıdır? Çünkü şu basit örnek için bile ne kadar uzun cümle yazıldı. Benim başım bir de suyunun suyu misali hesaplamalarla başım dertte olduğu için bunun pratik bir çözümüne ihtiyacım var. Tabi böyle bir çözüm varsa :) .
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
bgoktas
Kıdemli Üye
Mesajlar: 769
Kayıt: 27 Nis 2004 10:32
Konum: istanbul

Mesaj gönderen bgoktas »

Kod: Tümünü seç

select *,DevamEtmediğiGün-RaporluOlduğuGün
from
(select ogr.No, ogr.Adi, ogr.Soyadi, 
(select sum(dvm.Devam) from Devam as Dvm where Dvm.No=Ogr.No and dvm.Tur='D') as 'DevamEtmediğiGün', 
(select sum(dvm.Devam) from Devam as Dvm where Dvm.No=Ogr.No and dvm.Tur='R') as 'RaporluOlduğuGün' 
from Ogrenci as ogr) as tmp
Kolay Gelsin...
akdatilla
Üye
Mesajlar: 292
Kayıt: 02 Nis 2006 06:04
Konum: Antalya

Mesaj gönderen akdatilla »

merhaba
hız konusunda nasıl bir sonuç çıkar tam olarak bilemiyorum (denemek gerekir). Ancak aşağıdaki şekilde kullanım bazı durumlarda kolaylık sağlayabilir.


Kod: Tümünü seç

SELECT OGR_NO, OGR_ADI, OGR_SOYADI,DevamEtmedigiGun,RaporluOlduguGun,DevamEtmedigiGun-RaporluOlduguGun AS MazeretsizDevamsizlik FROM 
(
select OGR.OGR_NO, OGR.OGR_ADI, OGR.OGR_SOYADI, 
(select sum(DVM.DVM_DEVAM) from DVM where DVM.DVM_OGR=OGR.OGR_NO and DVM.DVM_TUR='D') as DevamEtmedigiGun, 
(select sum(DVM.DVM_DEVAM) from DVM where DVM.DVM_OGR=OGR.OGR_NO and DVM.DVM_TUR='R') as RaporluOlduguGun
from OGR
) AS T1
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

Bir ara hız testi yapar yazarım ama bu sorgu süppeerrrr!... Tahminime göre bu tür sorgu benim yazdığıma göre daha hızlı olmalı diye düşünüyorum ama belli olmaz. Çok sağolun. Buna benzer birşeyi SQL'e ilk dadandığım sıralarda gördümdü ama bir türlü as TBL'yi beceremedimdi. Çok teşekkür ederim acayip işime yarayacak bu sorgu.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
conari
Üye
Mesajlar: 2102
Kayıt: 27 Nis 2006 03:10
Konum: İstanbul & Gebze Karışık

Mesaj gönderen conari »

akdatilla yazdı:merhaba
hız konusunda nasıl bir sonuç çıkar tam olarak bilemiyorum (denemek gerekir). Ancak aşağıdaki şekilde kullanım bazı durumlarda kolaylık sağlayabilir.


Kod: Tümünü seç

SELECT OGR_NO, OGR_ADI, OGR_SOYADI,DevamEtmedigiGun,RaporluOlduguGun,DevamEtmedigiGun-RaporluOlduguGun AS MazeretsizDevamsizlik FROM 
(
select OGR.OGR_NO, OGR.OGR_ADI, OGR.OGR_SOYADI, 
(select sum(DVM.DVM_DEVAM) from DVM where DVM.DVM_OGR=OGR.OGR_NO and DVM.DVM_TUR='D') as DevamEtmedigiGun, 
(select sum(DVM.DVM_DEVAM) from DVM where DVM.DVM_OGR=OGR.OGR_NO and DVM.DVM_TUR='R') as RaporluOlduguGun
from OGR
) AS T1
@saban hoca'ma +1

Böyle sorguları bende basitleştirememiştim hep uzun yol çiziyorum
veya bir view oluşturup konuda geçen Devamsızlık-RaporluGün gibi alanları view içinde olan bu alanları birbirinden çıkarak sonuca gidiyorum.

Kod: Tümünü seç

select * , Devamsızlık-RaporluGün from olusturduğumview 
fırsat bulunca bende incelemye çalışacağım
Bir kelimenin anlamını öğretsen bile yeter..
ResimResim
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

Şöyle bir query daha sade ve standarda yakın olmaz mı:

Kod: Tümünü seç

SELECT
  T1.OGR_NO,
  T1.OGR_ADI,
  T1.OGR_SOYADI,
  SUM(CASE WHEN T2.DVM_TUR = 'D' THEN T2.DVM_DEVAM ELSE 0 END) AS DevamEtmedigiGun,
  SUM(CASE WHEN T2.DVM_TUR = 'R' THEN T2.DVM_DEVAM ELSE 0 END) AS RaporluOlduguGun,
  SUM(CASE WHEN T2.DVM_TUR = 'D' THEN T2.DVM_DEVAM
      WHEN T2.DVM_TUR = 'R' THEN -T2.DVM_DEVAM ELSE 0 END) AS MazeretsizDevamsizlik
FROM OGR T1
  LEFT JOIN DVM T2 ON T2.DVM_OGR = T1. OGR_NO AND T2.DVM_TUR IN ('D', 'R')
GROUP BY T1.OGR_NO, T1.OGR_ADI, T1.OGR_SOYADI
Tabi performansı nasıl olur ona da bakmak lazım.

İyi çalışmalar.
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

Öyle bir sorgu da gayet yakışıklı (ayrıca hızlı oduğunu düşünüyorum) olsa da alt tarafı bir çıkarma işlemi için yazılan kodun uzunluğuna dikkat çekmek isterim. Sorumda da belirttiğim gibi suyuynun suyu misali hesaplamaları yazmak çıldırtıcı olabiliyor. Denedim ve SQL Server için bu teknik tatmin edici derecede hızlı çalışmaktadır. Ayrıca konuyla alakası yok ama; not olarak belirtmek isterim ki, dönen kayıt setinde kayıt sayısı ne kadar az ise sorgular o kadar hızlı sonuçlanıyorlar. İyi çalışmalar.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Cevapla