T-SQL de Rekürsif Select ifadesi yazmak

Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Benim Bir SQL Select sorgum var fakat bu sorgunun döndürdüğü satırlar arasında listelenmesini istemediğim satırlar var.
Sorgumda her portföy numaralı satırın enfazla 1 kez listelenmesini istiyorum.Ve bu satırlar Statno alanındaki bilgi en büyük değere sahip satırlar olmalı...

Diyelimki benim sorgum şu şekilde bir sonuç döndürüyor

Portföy No Statno
1905 1
1905 2
1905 3
1906 2
1906 3
1907 1
1908 4

Sizin düzenleyeceğiniz kod ise şu sonucu döndürmeli...

Portföy No Statno
1905 3
1906 3
1907 1
1908 4


SORGU :==================================================================

SELECT LG_086_CLCARD.CODE AS Kodu, LG_086_CLCARD.DEFINITION_ AS Ünvanı, LG_086_01_CSCARD.DOC AS Türü,
LG_086_01_CSCARD.CURRSTAT AS Statü, LG_086_01_CSCARD.PORTFOYNO AS [Portföy No], LG_086_01_CSCARD.SERINO AS [Seri No],
LG_086_01_CSCARD.CITY AS Şehir, LG_086_01_CSCARD.OWING AS Borçlu, LG_086_01_CSCARD.DUEDATE AS Vade,
LG_086_01_CSCARD.SETDATE AS [İşl.Tarihi], LG_086_01_CSCARD.AMOUNT AS TUTAR, LG_086_01_CSTRANS.TRCODE AS Türü,
LG_086_01_CSTRANS.STATNO AS Sırası
FROM LG_086_CLCARD INNER JOIN
LG_086_01_CSTRANS ON LG_086_CLCARD.LOGICALREF = LG_086_01_CSTRANS.CARDREF INNER JOIN
LG_086_01_CSCARD ON LG_086_01_CSTRANS.CSREF = LG_086_01_CSCARD.LOGICALREF
GROUP BY LG_086_CLCARD.CODE, LG_086_CLCARD.DEFINITION_, LG_086_01_CSCARD.DOC, LG_086_01_CSCARD.SERINO, LG_086_01_CSCARD.CITY,
LG_086_01_CSCARD.OWING, LG_086_01_CSCARD.DUEDATE, LG_086_01_CSCARD.SETDATE, LG_086_01_CSCARD.AMOUNT,
LG_086_01_CSTRANS.TRCODE, LG_086_01_CSTRANS.STATNO, LG_086_01_CSCARD.CURRSTAT, LG_086_01_CSCARD.PORTFOYNO
HAVING (LG_086_01_CSCARD.DUEDATE > CONVERT(DATETIME, '2009-02-13 00:00:00', 102)) AND (LG_086_CLCARD.CODE LIKE 'M%')
======================================================================

Yardımlarınızı bekliyorum,

Kolay gelsin , iyi çalışmalar....

Ersoy Aydın
Logo Sistem Uzmanı
http:\\www.lsuersoy.gen.tr
 

beab05

Özel Üye
Katılım
19 Mart 2007
Mesajlar
1,418
Excel Vers. ve Dili
Office 2013
Merhabalar;
Daha iyi test etmeniz için scriptleri de veriyorum..

Önce tablomuzu ismi "excel" yapalım ve verileri yerleştirelim..
Kod:
CREATE TABLE [Excel] (
  [id] int IDENTITY(1, 1) NOT FOR REPLICATION NOT NULL PRIMARY KEY,
  [PortfoyNo] nchar(10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
  [StatNo] nchar(10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
)
ON [PRIMARY]
GO


/* Data for the `Excel` table  (Records 1 - 7) */


INSERT INTO [Excel] ([id], [PortfoyNo], [StatNo])
VALUES (1, N'1905', N'1')
GO

INSERT INTO [Excel] ([id], [PortfoyNo], [StatNo])
VALUES (2, N'1905', N'2')
GO

INSERT INTO [Excel] ([id], [PortfoyNo], [StatNo])
VALUES (3, N'1905', N'3')
GO

INSERT INTO [Excel] ([id], [PortfoyNo], [StatNo])
VALUES (4, N'1906', N'2')
GO

INSERT INTO [Excel] ([id], [PortfoyNo], [StatNo])
VALUES (5, N'1906', N'3')
GO

INSERT INTO [Excel] ([id], [PortfoyNo], [StatNo])
VALUES (6, N'1907', N'1')
GO

INSERT INTO [Excel] ([id], [PortfoyNo], [StatNo])
VALUES (7, N'1908', N'4')
GO
Alttaki sorgu yardımıyla da istediğimiz verileri elde ederiz.. Siz kendi tablonuza göre uyarlarsınız..

Kod:
SELECT bb.* FROM( 
    SELECT Portfoyno,MAX(statno) AS MaxSayı
    FROM excel 
    GROUP BY portfoyno) x 
    JOIN excel bb ON x.portfoyno =bb.portfoyno 
    AND x.MaxSayı =bb.statno
    ORDER BY portfoyno
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Teşekkürler

Merhabalar ,

ilginize teşekkür ederim.

Bu uygulamayı ilk önce SQL kodu olarak çözümlemeyi düşünüyorum.
Çünkü oluşturacağım koda daha sonradan yeni tablolar ve yeni bilgiler çekmeyi düşünüyorum...


Cevabınıza göre :

burada MAX ın sonuç çevirebilmesi için sanırım iç içe select kullanıyoruz...
Örneğinizi kendi sorguma adapte etmeye çalışacağım.

Tekrar teşekkürler

Kolay gelsin , iyi çalışmalar....
 

beab05

Özel Üye
Katılım
19 Mart 2007
Mesajlar
1,418
Excel Vers. ve Dili
Office 2013
Merhaba;

Çözüm zaten SQL iledir, verdiğim tablo oluşturma ve insert ten oluşan SQL scripti kafanızı karıştırmasın o sadece alttaki sorgunun çalışabilmesi içindi, yani test etmeniz içindi.. New query deyip scripti yapıştırıp çalıştırabilirsiniz daha sonra yine query de sorguyu deneyebilirsiniz.

Elbette benim de bahsettiğim kendi tablonuza uyarlamanızdır..

Sorguyu da biraz açıklamak gerekirse, aynı tablonun, farklı bir aliası ile join yapıp her iki tabloda portfoyno larının ve StatNo sayısının MAXStatNo sayıları ile arasında eşleşenleri vermesidir.
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Tekrar Merhaba ;

Göndermiş olduğunuz ilk kod Excel Tablesini (Sadece Fieldları) SQL 2000 de oluşturdu.Value değerler field alanlarına insert edilemedi...

Değerleri elle girdim.

ikinci sorgu ise şu hatayı çeviriyor...

Server: Msg 156, Level 15, State 1, Line 5
Incorrect syntax near the keyword 'JOIN'.

sorgudaki X ve bb birer alias mı ?

"bb." neyi ifade ediyor. ?

teşekkürler



Not : Bu mesajı yazarken ikinci cevabınızı görmemiştim.
 

beab05

Özel Üye
Katılım
19 Mart 2007
Mesajlar
1,418
Excel Vers. ve Dili
Office 2013
SQL 2000 belki de as deyimini istiyor olabilir siz "as x" ve "as bb" olarak deneyiniz..
Evet her ikisi de aliastır "bb." diyerek "bb" aliaslı tablodan ilgili alanı al diyoruz..
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
SQL 2000 belki de as deyimini istiyor olabilir siz "as x" ve "as bb" olarak deneyiniz..
Evet her ikisi de aliastır "bb." diyerek "bb" aliaslı tablodan ilgili alanı al diyoruz..
Enteresan birşey yakaladım , sadece aşağıdaki kod bloğu istediğim sonucu veriyor...bunu nasıl yorumlarsınız...

SELECT PortfoyNo,MAX(StatNo) AS MaxSayı
FROM Excel
GROUP BY PortfoyNo
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Yukarıdaki Sorgu bloğuna göre

Sorgumu adapte etmek istedim ama resimdeki hatayı aldım




 
Son düzenleme:
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Başarısız sonuç döndüren kodu şu şekilde sadeleştirdim....

SELECT
KART2.PORTFOYNO AS [Portföy No],
MAX(TRANS.STATNO) AS Sırası,
KART.CODE AS Kodu,
KART.DEFINITION_ AS Ünvanı,
KART2.DOC AS Türü,
KART2.CURRSTAT AS Statü,
KART2.SERINO AS [Seri No],
KART2.CITY AS Şehir,
KART2.OWING AS Borçlu,
KART2.DUEDATE AS Vade,
KART2.SETDATE AS [İşl.Tarihi],
KART2.AMOUNT AS TUTAR,
TRANS.TRCODE AS Türü
FROM LG_086_CLCARD AS KART
INNER JOIN LG_086_01_CSTRANS AS TRANS ON KART.LOGICALREF = TRANS.CARDREF
INNER JOIN LG_086_01_CSCARD AS KART2 ON TRANS.CSREF = KART2.LOGICALREF
GROUP BY KART2.PORTFOYNO,KART.CODE,KART.DEFINITION_,KART2.DOC, KART2.SERINO,KART2.CITY,
KART2.OWING, KART2.DUEDATE, KART2.SETDATE, KART2.AMOUNT,
TRANS.TRCODE, TRANS.STATNO, KART2.CURRSTAT
HAVING(KART2.DUEDATE > CONVERT(DATETIME, '2009-02-13 00:00:00', 102)) AND (KART.CODE LIKE 'M%')
 

beab05

Özel Üye
Katılım
19 Mart 2007
Mesajlar
1,418
Excel Vers. ve Dili
Office 2013
Enteresan birşey yakaladım , sadece aşağıdaki kod bloğu istediğim sonucu veriyor...bunu nasıl yorumlarsınız...

SELECT PortfoyNo,MAX(StatNo) AS MaxSayı
FROM Excel
GROUP BY PortfoyNo
;) Sadece belirli alana göre elbete çalışır bu sorgu ama yanına bir alan daha ekleyin ve sonucu görün.. Tabii ki çalışmayacak..
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Mesele de bu zaten , çok fazla alan çok fazla tablodan olunca , işler sarpa sarıyor....

JOIN ler ve iç içe SELECT ler ile umarsızca oynuyorum....birde gerçekten anlayarak yapabilecek durumda olsaydım...böyle bir sorgu için nerede ise 48 saattir araştırma yapıyorum...kaynaklar hep TEK TABLE ve TEK FIELD üzerine verilmiş , kimse 3-4 Table ve 8-9 field lı bir örnek yayımlamamış...
 

beab05

Özel Üye
Katılım
19 Mart 2007
Mesajlar
1,418
Excel Vers. ve Dili
Office 2013
Bakın kendiniz de dediniz örnekler tek table üzerine, çünkü kurgusu tasarımı daha kolay istenilen sorgu sonucunu almak için..

Bu sebeple siz 2 ya da daha fazla tablodan oluşan bir view yapın kriter olmasın.. Sonra bu tek view üzerinden benim verdiğim sorguya göre yapın.. Kesinlike çok daha kolay olacaktır. Bu yöntemle alan sayısı da önemsiz ;)
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Bu da bir çözüm teşekkür ederim , aklıma gelmemişti teşekkürler....
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Fakat ::frown:

Bu view içerisinden de istediğim bilgileri süzemiyorum...:redface::frown:
 

beab05

Özel Üye
Katılım
19 Mart 2007
Mesajlar
1,418
Excel Vers. ve Dili
Office 2013
View in alanlarını ya da select all cümlesini verir misiniz?

Sonuç sorgusunun kaynağını da bu "view" yaptınız değil mi?
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
View

SELECT DISTINCT
dbo.LG_086_CLCARD.CODE AS Kodu, dbo.LG_086_CLCARD.DEFINITION_ AS Ünvanı, dbo.LG_086_01_CSCARD.DOC AS Turu,
MAX(dbo.LG_086_01_CSCARD.CURRSTAT) AS Statü, dbo.LG_086_01_CSCARD.PORTFOYNO AS [Portföy No],
dbo.LG_086_01_CSCARD.SERINO AS [Seri No], dbo.LG_086_01_CSCARD.CITY AS Şehir, dbo.LG_086_01_CSCARD.OWING AS Borçlu,
dbo.LG_086_01_CSCARD.DUEDATE AS Vade, dbo.LG_086_01_CSCARD.SETDATE AS [İşl.Tarihi], dbo.LG_086_01_CSCARD.AMOUNT AS TUTAR,
dbo.LG_086_01_CSTRANS.TRCODE AS Türü, dbo.LG_086_01_CSTRANS.STATNO AS Sırası
FROM dbo.LG_086_CLCARD INNER JOIN
dbo.LG_086_01_CSTRANS ON dbo.LG_086_CLCARD.LOGICALREF = dbo.LG_086_01_CSTRANS.CARDREF INNER JOIN
dbo.LG_086_01_CSCARD ON dbo.LG_086_01_CSTRANS.CSREF = dbo.LG_086_01_CSCARD.LOGICALREF
GROUP BY dbo.LG_086_CLCARD.CODE, dbo.LG_086_CLCARD.DEFINITION_, dbo.LG_086_01_CSCARD.DOC, dbo.LG_086_01_CSCARD.SERINO,
dbo.LG_086_01_CSCARD.CITY, dbo.LG_086_01_CSCARD.OWING, dbo.LG_086_01_CSCARD.DUEDATE, dbo.LG_086_01_CSCARD.SETDATE,
dbo.LG_086_01_CSCARD.AMOUNT, dbo.LG_086_01_CSTRANS.TRCODE, dbo.LG_086_01_CSTRANS.STATNO, dbo.LG_086_01_CSCARD.CURRSTAT,
dbo.LG_086_01_CSCARD.PORTFOYNO
HAVING (dbo.LG_086_CLCARD.CODE LIKE 'M%')
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
View in alanlarını ya da select all cümlesini verir misiniz?

Sonuç sorgusunun kaynağını da bu "view" yaptınız değil mi?
Bu view dan Basit Sonuç sorgusu tetiklediğimde.

sadece 2 alan için...

Bu view dan dönmesini istediğim sonucun Query si şu

SELECT MAX(Sırası) AS Sırası, [Portföy No] AS Portfoy
FROM V_86_CEK_SENET
WHERE (Vade > CONVERT(DATETIME, '2009-02-17 00:00:00', 102))
GROUP BY [Portföy No]

bu başarılı sonuç döndürüyor....ama sadece 2 field için.....

Oysa bana Cari Hesap Ünvanı , Vade Tarihi , İşlem Tarihi , Tutar , Borçlu gibi alanlar da lazım...

bu alanalrıda SELECT ifadesine eklediğimde SONUÇ hatalı çıkıyor...Mükerer Portföy numarlarıda geliyor...

demek ki MAX fonksiyonu aynı tablodan iki farklı alana göre kaynak-hedef ilişkisinde doğru sonuç üretiyor...."Portföy numaralarına göre StatNo alanında MAX olan değerleri getir" dediğimizde doğru sonuç geliyor....

"Portföy numaralarına göre StatNo alanında MAX olan değerleri ve Cari Hesap Ünvanını , Tutarı , Vade Tarihini vs..vs..getir" dediğimizde ,Portföy numaraları BENZERSİZ olan , StatNo MAX olan değerler gelmesi gerekirken MAX olmayan değerler de gelebiliyor....en tersan olan bu gelen bilgileri uygulama tarafında karşılaştırdığım da ANORMAL bir farklılık görememem...

Bu noktada Microsoft un bir eksikliği veya bir KURALI olduğunu düşünmeye başladım...ve bu kuralı malesef ben bilmiyorum...
 

beab05

Özel Üye
Katılım
19 Mart 2007
Mesajlar
1,418
Excel Vers. ve Dili
Office 2013
Merhabalar;

Yaptığınız ve kaydettiğiniz viewin ismini VIEW_ISMI olarak kabul ettim. Altaki sorguyu new query'de deneyiniz.. Alan isimlerinde hata yapmadıysam çalışması gerekir..

SELECT bb.* FROM(
SELECT dbo.LG_086_01_CSCARD.PORTFOYNO ,MAX(dbo.LG_086_01_CSTRANS.STATNO) AS MaxSayı
FROM VIEW_ISMI
GROUP BY dbo.LG_086_01_CSCARD.PORTFOYNO) AS x
JOIN VIEW_ISMI AS bb ON x.dbo.LG_086_01_CSCARD.PORTFOYNO =bb.dbo.LG_086_01_CSCARD.PORTFOYNO
AND x.MaxSayı =bb.dbo.LG_086_01_CSTRANS.STATNO
ORDER BY dbo.LG_086_01_CSCARD.PORTFOYNO



Microsoftun eksikliği değildir başınıza gelen. Siz aynı değere sahip alanları gruplandırarak;

SELECT MAX(Sırası) AS Sırası, [Portföy No] AS Portfoy
FROM V_86_CEK_SENET
WHERE (Vade > CONVERT(DATETIME, '2009-02-17 00:00:00', 102))
GROUP BY [Portföy No]


bu sorguya göre sonuç alırsınız ama dediğiniz gibi aynı gruba ait farklı değerlere sahip diğer alanlar da girdi mi işin içine bu sefer bu sorgu yapısı işe yaramaz olur. Çünkü gruplanmış alanlara ait farklı değerler var ve bunların gruplanması söz konusu olmaz farklı oldukları için. Bu sefer gruplandırma yapılmış sorgudaki where ya da having te anlamını kaybedebilir. Bu tür sorunları aşmanın en iyi yolu istenilen sonuçları adım adım başka sorgularla almak ve oluşan sorgular üzerinden işlem yapmaktır..
 
Katılım
29 Haziran 2005
Mesajlar
158
Excel Vers. ve Dili
MS Office Professional Plus 2013 64 Bit -Eng
MSSQL 2012 R2 64 Bit
Tekrar Merhaba ;

Yeşil punto ile yazdığınız sorgunuz Query analyzer da hatalara takılıyor...

Fakat ;

Sorgunun neden doğru sonuç vermediğini açıklamanız yeterli oldu..."Aynı değerleri içeren bir Field,başka bir field ile farklı değerler ile ilişkili ise gruplama uygulanması anlamsız olur.." eğer bu teori doğru ise ben baştan beri hata yapıyorum demektir...UNIQ olmayan Portfoy No alanında gruplama yapıyordum...demek ki hataya neden olan bu.

Portföy No ya göre ORDER sıralaması yapabilirim...ama gruplama yapamam.Çünkü ilgili alan da bir değer ANA tabloda 5-6 kez yer alabilir ve bu alan ile ilişkili ihtiyaç duyduğum diğer veri de 5-6 farklı değere sahip olabilir...bu durumda Portföy no ya göre TEK satır bilgi çekmem imkansız....Çok satır bilgi çekip bu bilgiler içerisinden başka bir kritere göre eleme yapmam gerekecek....

aslında aklıma şöyle bir çözüm geliyor...

yeni bir tablo oluşturup içine istediğim sonucu sadece 2 field için doğru veren Query yi ekleyeyim...

sonra Mükerer kayıt listeleyen querymi de başka bir Tabloya çekeyim...

sonra bu tabloları doğru olan küçük tabloya göre birleştireyim...

Şimdi bir aşama kaydettiğimizi düşünüyorum....

sıradaki Sorun iki tablo nasıl soldakine göre NASIL birleştirilir?

Cevabınızı bekliyorum....

Kolay gelsin , iyi çalışmalar....
 
Üst