Delphi Can

Orjinalini görmek için tıklayınız: Trew View yapısında olan veriden Root kaydına nasıl ulaşılır
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Selamlar

Veri olarak bir ürün ağacı mevcut.
Bu veriye göre her satırdaki kaydın en tepe noktasındaki ust koda ulaşmam gerekiyor.
Sonuç olarak sorgunun sonucunda elimde ustkod, altkod ve rootkod olmalı

Bu işlemi yaparken alt bir fonksiyon yapıp bu fonksiyonu recursive çağırmak istemiyorum
yada cursor olmadan bir yolu varmıdır.

Teşekkürler

Örneğin
9AM-TSS43-0016 > 1-300-D215 > 9AM-TSS43-0016
9AM-TSS43-0016 > 6-02-7016 > 9AM-TSS43-0016
6-02-7016 > 1-700-125 > 9AM-TSS43-0016
6-02-7016 > 2-160-026 > 9AM-TSS43-0016
2-160-026 > 1-160-112 > 9AM-TSS43-0016
2-220-001 > 0-220-002 > 9AM-TSS43-0016
2-220-004 > 0-220-009 > 9AM-TSS43-0016
2-150-052 > 0-BM-4321 > 9AM-TSS43-0016
0-BM-4321 > 0-142-021 > 9AM-TSS43-0016
0-BM-4321 > 0-142-043 > 9AM-TSS43-0016

105.2.04.13 > 2-EB-101 > 105.2.04.13
2-EB-101 > 0-BM-0949 > 105.2.04.13
0-BM-0949 > 0-142-009 > 105.2.04.13
0-BM-0949 > 0-142-105 > 105.2.04.13


Declare @Mamul_Agaci Table (ustkod Varchar(20), altkod Varchar(20))
Insert Into @Mamul_Agaci (ustkod, altkod)

 Select '9AM-TSS43-0016', '1-300-D215' Union All
 Select '9AM-TSS43-0016', '6-02-7016'  Union All
 Select '6-02-7016',      '1-700-125'  Union All
 Select '6-02-7016',      '2-160-026'  Union All
 Select '2-160-026',      '1-160-112'  Union All
 Select '6-02-7016',      '6-01-1100'  Union All
 Select '6-02-7016',      '6-01-1121'  Union All
 Select '6-01-1121',      '1-100-009'  Union All
 Select '6-01-1121',      '1-122-081'  Union All
 Select '6-01-1121',      '2-140-058'  Union All
 Select '2-140-058',      '2-221-054'  Union All
 Select '2-221-054',      '0-220-004'  Union all
 Select '2-221-054',      '0-220-005'  Union All
 Select '2-221-054',      '0-220-012'  Union All
 Select '2-221-054',      '0-220-014'  Union All
 Select '2-221-054',      '0-220-024'  Union All
 Select '2-221-054',      '0-220-064'  Union All
 Select '2-221-054',      '2-220-001'  Union All
 Select '2-220-001',      '0-220-002'  Union all
 Select '2-220-001',      '0-220-003'  Union all
 Select '2-221-054',      '2-220-004'  Union all
 Select '2-220-004',      '0-220-009'  Union all
 Select '2-220-004',      '0-220-019'  Union all
 Select '6-01-1121',      '2-150-052'  Union all
 Select '2-150-052',      '0-BM-4321'  Union all
 Select '0-BM-4321',      '0-142-021'  Union all
 Select '0-BM-4321',      '0-142-043'  Union all
 
--
 Select '105.1.0413',     '2-EB-101'   Union all
 Select '2-EB-101',       '0-BM-0949'  Union all
 Select '0-BM-0949',      '0-142-009'  Union all
 Select '0-BM-0949',      '0-142-105'  Union all
 Select '2-EB-101',       '4-EB-020'   Union all
--
 Select '105.2.04.13',    '2-EB-101'   Union all
 Select '2-EB-101',       '0-BM-0949'  Union all
 Select '0-BM-0949',      '0-142-009'  Union all
 Select '0-BM-0949',      '0-142-105'

 Select * From @Mamul_Agaci
[attachment=2505]
Selamlar,
Sorunuzu çok iyi anlamadım, bu nedenle yanıt veremiyorum. Sorunuzun kapsamı MSSQL server'de Query yapmakla mı ilgili, yoksa TTreeView'de bir işlem mi? Bunları daha açık belirtirseniz belki yardımcı olabilir buradaki insanlar. Eğer MSSQL'de recursive bir yapı istiyorsanız şu şekilde yapabilirsiniz :

   
with ctePermissions as(
 select PermissionId, ParentId, 0 as Level from secinUserBasePermissions(@UserId)
 union all
 select p.PermissionId, p.ParentId, Level + 1 from  secPermission p
    inner join ctePermissions c on c.PermissionId=p.ParentId
where ISNULL(p.[IsActive], 1)=1
)
select @retval=count(*) from ctePermissions where ','+@RequiredRights+',' like '%,'+CAST(PermissionId as varchar(20))+',%'
return @retval;

Eğer bu dökümanın tamamını görmek istiyorsanız şu linkten erişebilirsiniz :https://github.com/mozpinar/FaturaOrnek/...FullDB.sql
@mustafaozpinar Üstadım yapmak istediğim
MSSQL Server üzerinde bir sorgu.
Bu sorgu birbirini çağıran bir alt sorgu olmayacak.
Bu sorgu bir cursor olmadan olacak.

Yaptığınız örnek ParentId şeklinde birbirini çağıdan ve bir sonraki kuralı belirleyen şeklinde bakınız (Level + 1) yazdığınız kısım.
Bendeki tablo yapısında bu tarzda birbirini bağlayan tek şey alt ve üst kodların birbirine olan bağıntısı

Varsayın bu tabloda RootKod diye bir 3.alan olsun
Ben Tree şemasındaki en üst bağ hariç altındaki tüm satırlara en üst bağın değerini update edeceğim.
Bunu döngü olmadan nasıl yaparım bütün sorun bu

Örnek 
[attachment=2507]
Selamlar,
Verdiğiniz biligilerden şunu söyleyebilirim,
Bir ağaç yapısından bahsedebilmek için bir üst kademe daldan 2 alt dal türerse bu alt dalların başka üst dalları olmaması gerekir. Yani ustkod alanı Unique olmalı.
Sizin küçük tablonuzda alt dalların birden fazla üst dalı var. Bu durumda Ağaç yapısından söz edilemez. Bu nedenle öncelikle datanızı derleyip toparlayıp ne yapmanız gerektiğine karar vermelisiniz.
Burada ustkod 0-BM-0949 olan 2 adet kayıt var, RootKod aynı olan, yani alt dallar, varsa bu alt dalları hangi ustkod'a bağlayacağız. Önce bu sorunu çözmeniz gerek.
SONUÇ : Yapınız bir ağaç yapısı değil. Önce datanızı ağaç yapısına getirmeniz gerekir.
@mustafaozpinar üstadım
bu yapıya o zaman organizasyon yapısı desek iş değişir mi.
Sonuc olarak 0-BM-0949 üstü yok ve her zaman için en üst kod tekil bir durumda
105.1.0413 yada 105.2.04.13 bu kodların daha üstü yok

Mesela ben alt kodların her birini ele alsam ve bir üstünü bularak en üsttekine erişsem bu durumda alttakilerin hepsinde bir üst olacak fakat son üst kodda üst olmayacaktır.

Declare @Mamul_AgaciRoot Table (ustkod Varchar(20), altkod Varchar(20), RootKod Varchar(20))

Declare @Mamul_Agaci Table (ustkod Varchar(20), altkod Varchar(20))
Insert Into @Mamul_Agaci (ustkod, altkod)
Select '105.2.04.13',    '2-EB-101' Union all
  Select '2-EB-101',       '0-BM-0949'Union all
  Select '0-BM-0949',      '0-142-009' Union all
  Select '0-BM-0949',      '0-142-105'

  Select * From @Mamul_Agaci


  Declare @UstKod Varchar(20) = null, @Altkod Varchar(20) = Null
  Declare @RootKod Varchar(20) = Null

  DECLARE Cursor_MA CURSOR local for 
    Select ustkod, altkod from @Mamul_Agaci
  open Cursor_MA  
  fetch next from Cursor_MA into @UstKod, @altkod
  WHILE @@FETCH_STATUS = 0
  BEGIN
      Select @RootKod = T.ustkod
      From @Mamul_Agaci T
        Left Join @Mamul_Agaci A On A.altkod = T.ustkod
      Where A.ustkod Is Null
            Group By T.ustkod

      Insert into @Mamul_AgaciRoot (ustkod, altkod, RootKod)
      Values (@UstKod, @Altkod, @RootKod)

      fetch next from Cursor_MA into @UstKod, @altkod
  END
  close Cursor_MA
  deallocate Cursor_MA

  Select * From @Mamul_AgaciRoot
        

[attachment=2508]
Selamlar,

Bu hiyerarşi tablolarında, daha doğrusu bunların SQL sorgulamalarında sirküler kodlamaMAya dikkat etmek gerekiyor öncelikle. Kendi bilgilerimi senin verilerine uyguladığımda sonuç alamadım. Sonra daha dikkatli inceleyince bunun nedeni olarak bir kayıtta ustkod ve RootKod alan değerlerinin aynı olduğunu farkettim ve bu, sorguyu sonsuz döngüye sokuyor. MSSQL de 100. seviye recursive sorgudan sonra hata verip atıyor. Şimdi dataları değiştirip kurallara uygun hale getirince sonuç alabildim.

Senin verileri şu şekilde düzenlediğim zaman
[attachment=2509]

ve sonunda şu sorguyu çalıştırdığımda
   
with cte_adfTest as(
    select ustkod, RootKod from adftest where ustkod='2-EB-101'
    union all
      select p.ustkod, p.RootKod from  adftest p
            inner join cte_adfTest c on c.RootKod=p.ustkod
         )
         select * from cte_adfTest;


Şu sonucu alıyorum

[attachment=2510]

Datayı circular olmayacak şekilde düzenlersen sen de bu sonucu alabilirsin.

Sonuç tablosunda tüm satırlar çift görünüyor, çünkü aradığım ustkod tabloda iki defa geçiyor.

EK:   ... on c.RootKod=p.ustkod kısmını ... on c.ustkod=p.RootKod  şeklinde değiştirirsek Üst düzeyden alt düzeye doğru gider. Yani tersi yönde gitmiş olur.
@mustafaozpinar üstadım
uğraşlarınız ve fikirleriniz çok değerli öncelikle teşekkür ederim.
Fakat sanırım yazdıklarımda bir eksik oldu ki anlatamadığımı düşünüyorum.
Tablo yapısında Elimde Root Alanı Yok ve bulmaya çalıştığım alan değeri bu zaten
her satır için kendisine bağlı en üst sırayı bulmaya çalışıyorum.
Elimde yaklaşık bu şekilde farklı mamul ağaçlarına ait 3500 civarı ana root olan ve alt bağları olan 120.000 civarı kayıt var
Ve elimdeki datalar ile bu sistem yaklaşık 15 yıldır çalışıyormuş.
Datalarda bir sorun olduğunu düşünmüyorum.
Buradaki amaç başta da belirtiğim gibi döngü yada recursive fonksiyon yapmadan çözülebilir mi bunu bulmaya çalışıyorum
Hocam çözüm recursive olacaktır.
Tam aynısı değil ama benzer mantıkla recete alt reçete alt reçete bakan otomatik sonsuz hesaplama yapan maliyet hesaplama yazmıştım. Bu tarz sonu bilinmeyen işlemler için vazgeçilmez recursive olacaktır. Postgres üzerinde yapmıştım
Merhaba bu gibi yapılarda bende cursorden kacıyorum. OUTER APPLY veya CROSS APPLY kullanıyorum.
Tablodunuz Kod ve UstKod alanları olsun.

Select mu.Kod as UstKod,
       ma.Altkod
FROM Mamul_Agaci mu
OUTER APPLY(Select m.Kod as AltKod
            FROM Mamul_Agaci m 
            WHERE m.Ustkod=mu.Kod
           ) as ma
(22-12-2023, Saat: 16:32)serdar Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba bu gibi yapılarda bende cursorden kacıyorum. OUTER APPLY veya CROSS APPLY kullanıyorum.
Tablodunuz Kod ve UstKod alanları olsun.

Select mu.Kod as UstKod,
       ma.Altkod
FROM Mamul_Agaci mu
OUTER APPLY(Select m.Kod as AltKod
            FROM Mamul_Agaci m 
            WHERE m.Ustkod=mu.Kod
           ) as ma

Selamlar hocam bu yöntem her kayıt için diğer dosyadaki karşılıkları bulacaktır böyle bir sorguyu yaptığınız 50 satır için milyonlarca satır gelecektir ki
yine de benim istediğim her satırın en üst kısmını bulmaz