2008-08-29 24 views
1

Aşağıdaki kodda, SQL Server 2005'te temel hiyerarşik bir yapının en üst düzey ebadını bulmak için özyinelemeli bir CTE (Ortak Tablo İfadesi) kullanıyorum. Bu hiyerarşinin kuralı, her CustID'nin bir ParentID'ye sahip olması ve eğer CustID'nin üst ailesi yoksa, o zaman ParentID = CustID olması ve en yüksek düzey olmasıdır.Yinelemeli bir CTE'de üretilen son kaydı nasıl alırsınız?

DECLARE @LookupID int 

--Our test value 
SET @LookupID = 1 

WITH cteLevelOne (ParentID, CustID) AS 
(
     SELECT a.ParentID, a.CustID 
     FROM  tblCustomer AS a 
     WHERE a.CustID = @LookupID 
    UNION ALL 
     SELECT a.ParentID, a.CustID 
     FROM  tblCustomer AS a 
     INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID 
     WHERE c.CustID <> a.CustomerID 
) 

Yani tblCustomer aşağıdaki gibiyse:

ParentID CustID 
5   5 
1   8 
5   4 
4   1 

Yukarıdaki koddan almak sonucudur: İstediğim o sonucun sadece son satır olan

ParentID CustID 
4   1 
5   4 
5   5 

:

ParentID CustID 
5   5 

How d o CTE'de üretilen en son kaydı (en yüksek CustID değeri olacak mı) döndürdüm?

Ayrıca, bu tabloda birden çok ilişkili olmayan CustID hiyerarşisi olduğunu unutmayın, bu nedenle SELECT * FROM tblCustomer WHERE ParentID = CustID değerini yapamıyorum. Kimlik numarası hiyerarşide nerede olduğuyla ilgili olmadığı için ParentID veya CustID tarafından sipariş veremiyorum.

cevap

2

Sadece en yüksek özyineleme derinliğini istiyorsanız, böyle bir şey yapamaz mıydınız? O zaman, gerçekten CTE'yi sorguladığınızda, sadece maksimum (Derinlik) satırı olan satırı aradınız mı? böylece gibi:

DECLARE @LookupID int 

--Our test value 
SET @LookupID = 1; 

WITH cteLevelOne (ParentID, CustID, Depth) AS 
(
     SELECT a.ParentID, a.CustID, 1 
     FROM  tblCustomer AS a 
     WHERE a.CustID = @LookupID 
    UNION ALL 
     SELECT a.ParentID, a.CustID, c.Depth + 1 
     FROM  tblCustomer AS a 
     INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID 
     WHERE c.CustID <> a.CustID 
) 
select * from CTELevelone where Depth = (select max(Depth) from CTELevelone) 

ya, Trevor önerdiklerini adapte, bu aynı CTE ile kullanılabilir:

select top 1 * from CTELevelone order by Depth desc 

Ben MüşteriKimliği ihtimaline karşı tarafından sipariş istediğini mutlaka olduğunu sanmıyorum Sen tarif ettin, ama ben de bu konuda tam olarak açık değildim.

1

ben tam sorunu anlamak, ama sadece deneyebilirsin ona & çizgi kesmek için değil eminim: MüştKimliği örnekte olduğu gibi sırayla da değil, varsayar

SELECT TOP 1 FROM cteLevelOne ORDER BY CustID DESC 

GUID gibi bir şey.

0

Öncelikle ebeveynlerden biri aynıysa, cte bitmez. Yinelemeli bir CTE olduğu için sonlandırılmalıdır. Ebeveyn ve cust id aynı olması, döngü bitmeyecek.

Msg 530, Düzey 16, Durum 1, Satır 15 Bildirimi sonlandırıldı. Maksimum yineleme 100, bildirimin tamamlanmasından önce tükendi.