2012-08-24 63 views
0

作为一个从未从SQL中获得任何人的指导/指导的人,我想听听你们如何进行下面的查询。从我所听到的,这样的循环是一种非常糟糕的做事方式。如何避免在此使用while循环?

我是从这个创造我的查询中的表:

DECLARE @maxReleases int 
SET @maxReleases = 100000 

DECLARE @RootReleases table (ReleaseId int, RootReleaseId int) 

DECLARE @ctr int 
Set @ctr = 1 

WHILE(@ctr <= @maxReleases) 
BEGIN 
WITH cte_Releases 
( 
    ReleaseId, 
    Name, 
    ParentReleaseID 

) 
AS( 
    SELECT 
    ReleaseId, 
    Name, 
    ParentReleaseID 

    FROM Releases 
    Where ReleaseId = @ctr 

UNION ALL 

SELECT 
    R.ReleaseId, 
    R.Name, 
    R.ParentReleaseID 
FROM Releases R 
INNER JOIN cte_Releases ON cte_Releases.ParentReleaseID = R.ReleaseId 
) 
INSERT INTO @RootReleases 
SELECT max(ReleaseId) as ReleaseId, min(ReleaseId) as RootReleaseId FROM cte_Releases 

SET @ctr = @ctr + 1 
END 

这段代码的目的是要建立连接的记录与他们最远的父记录表,并将其插入一个表格来引用查询中的其他地方。

回答

0

我没有数据要测试,所以告诉我如果沿着这些线路运行某些内容,会发生什么情况。 应该可以使用group by和aggregates。 如果您提供样本数据,我可能会提供更多帮助。

 DECLARE @RootReleases table (ReleaseId int, RootReleaseId int) 

; WITH cte_Releases 
( 
    ReleaseId, 
    Name, 
    ParentReleaseID 

) 
AS( 
    SELECT 
    ReleaseId, 
    Name, 
    ParentReleaseID 

    FROM Releases 
-- Where ReleaseId = @ctr 

UNION ALL 

SELECT 
    R.ReleaseId, 
    R.Name, 
    R.ParentReleaseID 
FROM Releases R 
INNER JOIN cte_Releases ON cte_Releases.ParentReleaseID = R.ReleaseId 
) 
INSERT INTO @RootReleases 
SELECT max(ReleaseId) as ReleaseId, min(ReleaseId) as RootReleaseId FROM cte_Releases 
WHERE ReleaseId BETWEEN 1 AND 100000 
GROUP BY ReleaseId