tek tabloda2 toplama sorgusu

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
yusuf simsek
Üye
Mesajlar: 330
Kayıt: 09 Mar 2004 11:18
Konum: Konya
İletişim:

tek tabloda2 toplama sorgusu

Mesaj gönderen yusuf simsek »

öncelikle tüm hocalarıma ve arkadaşlarıma selamlar....

sorunum kolay gibi ama bana biraz karışık geldi ve bilgim yetersiz :oops:

daha önce pentiumkıvanc arkadaşım benzer bir soru sormuş ve naile hanım aşağıdaki cevabı vermiş...
Select(Select Sum(case islemtipi when G then miktar) - Sum(case islemtipi when C then miktar)
from TABLO where (tarih<12/07/2004)) as [Devreden],
(Select Sum(case islemtipi when G then miktar) - Sum(case islemtipi when C then miktar)
from TABLO where (tarih=12/07/2004))as [Bugun]
FROM TABLO
( viewtopic.php?t=3734&highlight=sum adresinden aldım )

inceledim ve uyguladım ama işin içinden çıkamadım ve sonuç alamadım...

Benim sorunum
stok hareket tablosunda giriş ve çıkış işlemlerini tutuyorum...
ürün kod numarasına göre giriş oranlarını ve çıkış oranlarını toplayıp cıkan toplamlarında farkını alacak...


stok hareket tablosunda kullanacağım alanlar...

Kod: Tümünü seç

ÜRÜN KOD    ADET    TUR  
1           10      GİRİS
2           10      GİRİS 
2           5       CIKIS
1           5       CIKIS 
ben bu işlemi 1 query nesnesi içinde yapıp alış toplamlarını, satış toplamlarını ve kalan ürün sayısını dbgrid üzerinde görmek istiyorum

herkese şimdiden çok teşekkür ederim
Bugün bir kez daha,
Hiç Birşey Bilmediğimi Öğrendim!!!

https://extrayazilim.com
Kullanıcı avatarı
fahrettin
Admin
Mesajlar: 2619
Kayıt: 11 Haz 2003 10:38
Konum: İstanbul
İletişim:

Mesaj gönderen fahrettin »

database nedir? Mesela soyle bir select olabilir....

Kod: Tümünü seç

Select URUN_KOD, sum(if TUR='GIRIS' then ADET else 0 endif) as GIRIS,
sum(if TUR='CIKIS' then ADET else 0 endif) as CIKIS,FARK=GIRIS-CIKIS
from TABLO
group by URUN_KOD
order bu URUN_KOD
Mesela bu kod sybase'de calisir... Fakat veritabanınızın ne olduguna bagli olarak ufak tefek degisiklikler yapmanız gerekebilir...
* http://www.fahrettin.org Manzara Fotoğraflarım... :)
* http://delphiturkiye.gunduz.info Seminerler... ;)
* http://www.hakmar.com.tr Kalite bir haktır... 8)
yusuf simsek
Üye
Mesajlar: 330
Kayıt: 09 Mar 2004 11:18
Konum: Konya
İletişim:

Mesaj gönderen yusuf simsek »

fahrettin hocam şuan dbase veri tabanı kullanıyorum...
(inşaallah firebird veya mysql e geçiş yapacağım ama zamanı belli değil..)

kodu denedim...IF döngüsünü kabul etmiyor..
Invalid use of keyword.
Token : if
Line number: 1.
hatasını veriyor...

hocam denemek için şu kodu yazdım...
SELECT S_hareket.URUN_NO, SUM( S_hareket.ADET ) G_ADET, S_hareket.TUR, SUM( S_hareket_1.ADET ) C_ADET, S_hareket_1.TUR
FROM "s_hareket.DBF" S_hareket
INNER JOIN "s_hareket.DBF" S_hareket_1
ON (S_hareket.URUN_NO = S_hareket_1.URUN_NO)
WHERE (S_hareket.TUR = 'g')
AND (S_hareket_1.TUR = 'c')
GROUP BY S_hareket.URUN_NO, S_hareket.TUR, S_hareket_1.TUR
query içinde tabloyu tekrar kendisiyle bağladım nasıl sonuç verir diye...
(saçmaladım ama denemeden öğrenilmiyo :D )
girişlerin toplamlarını doğru veriyor....
çıkışların toplamlarını iki katı olarak veriyor...

sebebini çıkış işlemlerinde iki kere işlem yapması olarak düşünüyorum...acaba düşüncem doğrumu?
Bugün bir kez daha,
Hiç Birşey Bilmediğimi Öğrendim!!!

https://extrayazilim.com
doganzorlu
Kıdemli Üye
Mesajlar: 395
Kayıt: 22 Tem 2004 09:15
Konum: İzmir
İletişim:

Mesaj gönderen doganzorlu »

Bu konuda bir otorite olmamakla birlikte birkaç noktaya değinmek isterim,

Fahrettin beyin verdiği query oldukça özel ve çoğu veritabanında çalışmayacaktır. Nedenleri ise;

1. case when end case clause ı genellikle ya desteklenmez yada syntax ı değişiktir (Progress ve MS SQL server için en azından)
2. nested query sonuçlarını AS ile bir değişkene atmak hemen hemen tüm SQL motorlarında mümkündür ve fakat bu değişkenleri aynı query içinde kullanmaya hepsi olanak sağlamazlar. (Yani mevcut = giren - cikan olan bölüm)


Bunula birlikte tablonuzun performans açısından endişe verici bir yapısı da mevcut. Ana query + 2 nested query ile bir hareket tablosundan bilgi derlenmesi SQL motoruna ciddi yük getirecektir. Eğer tabloyu değiştirme olanağı yok diyorsanız hiç olmazsa;

1. Urun + tip şeklinde bir index ekleyiniz
2. tip alanını 'GIRIS' 'CIKIS' şeklindeki char tipinden 1 ve 2 gibi değerleri alabilecek integer bir alana dönüştürünüz. Response süreleri acayip farkedecektir.

Yok fikirlere açığım diyorsanız olması gereken tablo ;

Kod: Tümünü seç

Urun    Giris    Cikis
A          10        0
B          20        0
C          30        0
A           0        5
B           0       10
C           0       15
Ve gereken sorgu;

SELECT sum(giris) as gtop,sum(cikis) as ctop FROM urun GROUP BY urun

grid e de bir calculate alan ekleyerek kalanı göstermek, client makinaya da işin azıcık da olsa bir kısmını yükleyebilmek adına daha yararlı olur..
Doğan Zorlu, İzmir

------------------------
"Bu Kitap'ı sana yalnız şunun için indirdik: Hakkında ayrılığa düştükleri şeyi onlara iyice açıklayasın ve Kitap, iman eden bir topluluk için kılavuz ve rahmet olsun." (NAHL 64)
Kullanıcı avatarı
naile
Admin
Mesajlar: 1873
Kayıt: 11 Haz 2003 10:11

Mesaj gönderen naile »

dbase de CASE var mı bilmiyorum ama Fahrettin Bey'in kodunun Case ile yapılmış hali:

Kod: Tümünü seç

Select URUN_KOD, sum(CASE TUR WHEN 'GIRIS' THEN ADET ELSE 0 END) as GIRIS, 
sum(CASE TUR WHEN 'CIKIS' THEN ADET ELSE 0 END) as CIKIS,FARK=GIRIS-CIKIS 
from TABLO 
group by URUN_KOD 
order bu URUN_KOD
Not : Buarada ms sql de AS diye isismlendirilen alan yukardaki gibi GIRIS-CIKIS şeklinde çağrılmasına izin vermiyor. Alın işte ms sql in bir eksiği daha :(
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2247
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Mesaj gönderen Kuri_YJ »

Selamlar,

Sağolsun Microsoft, bize SQL'de nasıl sağlam Query yazılır öğrettiği için size basit, yavaş ama sağlam bir Query yazacağım.

Kod: Tümünü seç

  SELECT UrunKod, (SELECT SUM(ADET) FROM HAREKETLER WHERE TUR = 'GİRİŞ') AS GIRIS_MIKTARI, (SELECT SUM(ADET) FROM HAREKETLER WHERE TUR = 'CIKIŞ') AS CIKIS_MIKTARI
FROM URUNLER
ORDER BY URUNLER
şeklinde kullanırsanız Giriş ve Çıkış Miktarlarını toplayabilirsiniz.

Ancak dikkat etmeniz gereken nokta şu. Yukarıdaki Query'de iki tablodan veriler çekiliyor.

1. Tablo URUNLER (Yani ürün tanımlarının olduğu tablo)
2. Tablo HAREKETLER (Yani giriş/çıkış hareketlerinin yapıldığı tablo)

Yukarıdaki Query'de hareket görmemiş olan ürünler de çıkacaktır. Bunları da Where Clause'ına eklentiler yaparak çözümleyebilirsiniz. Ayrıca Calculated field ekleyerek de Fark diye bir kolon açabilirsiniz.

Doğan'ın söylediği gibi table structure'ınızı değiştirirseniz daha iyi olur.

Bu arada Doğan seni aramaızda görmek büyük onur doğrusu :)

Sevgiler
Kolay Gelsin.
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
yusuf simsek
Üye
Mesajlar: 330
Kayıt: 09 Mar 2004 11:18
Konum: Konya
İletişim:

Mesaj gönderen yusuf simsek »

doğan hocam verdiğiniz bilgilerden dolayı teşekkür ederim...

ufak çaplı bir proje olduğu için değiştirme işlemi çok büyük sorunlar oluşturmaz...

peki değiştirme konusunda sizin tavsiyeniz ne olur....

tablo için çalışma mantığım....

Kod: Tümünü seç

tablo alanları => kayıt_no, firma ,urun no,birim fiyat,adet,toplam,tarih,tur
ürün alışı yapıldığında bilgileri tabloya kaydediyor..
tür alanına g değerini otomatik atıyo
ürün satışı yapıldığında da bilgileri tabloya kaydediyor ve tür alanına c değerini atıyor

stok durumu sorgulayacağında ürün numarasına göre alışları ve satışları toplayıp farkını alacak ve bu üç sonucuda tek dbgrig üzerinde gösterecek...

tek grid üzerinde göstermek için işlemi tek query nesnesinde yapmak istiyorum...bu şekilde bir mantık kurdum.... tek query kullanmak istediğim içinde bilgim yetersiz kaldı...

şu an tabloyu değiştirip tekrar uygulayacağım

çok teşekkür ederim
Bugün bir kez daha,
Hiç Birşey Bilmediğimi Öğrendim!!!

https://extrayazilim.com
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2247
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Mesaj gönderen Kuri_YJ »

Yaw Query'i yanlış yazmışım :) MS'e laf aterken üstümüze çamur sıçradı :) Hehehehehe

Kod: Tümünü seç

SELECT URUNLER.UrunKod, (SELECT SUM(HAREKETLER.ADET) FROM HAREKETLER WHERE HAREKETLER.TUR = 'GİRİŞ' AND HAREKETLER.UrunKod = URUNLER.UrunKod) AS GIRIS_MIKTARI, (SELECT SUM(HAREKETLER.ADET) FROM HAREKETLER WHERE HAREKETLER.TUR = 'CIKIŞ' AND HAREKETLER.UrunKod = URUNLER.UrunKod) AS CIKIS_MIKTARI 
FROM URUNLER 
ORDER BY UrunKod
şeklinde veya buna benzer ama Where clause'larında tarih kontrolleri filan eklenmiş birşeyler olması lazım :)

Kolay Gelsin.
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
yusuf simsek
Üye
Mesajlar: 330
Kayıt: 09 Mar 2004 11:18
Konum: Konya
İletişim:

Mesaj gönderen yusuf simsek »

olay tamamdır.......

Kod: Tümünü seç

SELECT URUN_NO,SUM( GIRIS ) TGIRIS, SUM( CIKIS ) TCIKIS, (SUM(GIRIS) - SUM(CIKIS)) KALAN
FROM "s_hareket.DBF" S_hareket
GROUP BY URUN_NO
doğan hocamın tavsiyesi üzerine tablodaki adet alanını kaldırıp giriş ve çıkış alanlarını koydum.yani tablo

kayıt_no, firma ,urun no, birim fiyat, toplam, tarih, tur , giris , cikis
alanlarından oluşturdum...

ama kalanı hesaplatmak için aynı alanları iki defa topladım.. bu olay performansı ne kadar etkiler bilmiyorum...

tahminim yarı yarıya performans düşecek ama hala calculated fiell sorunumu çözemedim...(çünki onunla daha tam olarak savaşa girmedim :twisted: )
viewtopic.php?t=4093

savaşı kazandığım da ilk iş olarak yukarıdaki kodu değiştireceğim

fahrettin hocama ,doğan hocama ve tüm arkadaşlara çok teşekkür ederim...
Bugün bir kez daha,
Hiç Birşey Bilmediğimi Öğrendim!!!

https://extrayazilim.com
Cevapla