t-sql:与父母,孩子,孙子孙女和孩子一起排队

时间:2011-03-28 12:34:39

标签: sql sql-server tsql

我有一个包含2列的表格:ID, ParentID

我想创建一个新表/视图,每行包括所有级别的所有子级给某个父母......

例如:

ParentID  Level_1  Level_2  Level_3 ... Level_n

这意味着parentID是Level_1的父级,它是级别2的父级,它是level_3的父级,依此类推......

我需要在没有递归的情况下这样做,所以没有机会堆叠溢出...

在T-SQL中有一个名为@@rowcount的函数,它返回我在最后一个选择中得到的行,所以也许我可以在while循环中使用它或什么......

问题是我怎么知道一开始要构建多少列? 任何想法如何应对这一挑战?

2 个答案:

答案 0 :(得分:1)

您想要获得的是数据透视表,但在我看来,此任务不属于数据库。我宁愿得到一个带行的结果集,并将它们“外部”转动。

为了实现我所描述的,在SQL Server 2005+中,您可以使用公用表表达式(here you can find an example,而SQL Server 2000需要稍微不同的方法。

注意:虽然你写了“没有递归所以没有机会堆叠溢出”,你仍然需要从无限循环中自我保护。我个人使用递归并为它建立一个最大的“深度”;当递归试图“超过”限制时,我会停止并返回错误。

答案 1 :(得分:0)

可以通过创建表值函数TVF来解决,该函数返回员工的整个树,其级别如下:

CREATE FUNCTION [dbo].[GetTree](@EmployeeID int)
RETURNS @Result Table
(   EmployeeID  int,
    IdParent int,
    Lvl int
)
AS
BEGIN
    declare @lvl int
    set @lvl=0
    while(@EmployeeID is not null)
    begin
        insert  into @Result
        select  EmployeeID,ManagerID,@lvl
        from    dbo.MyEmployees
        where   EmployeeID=@EmployeeID

        select  @EmployeeID=ManagerID,
                @lvl=@lvl+1
        from    dbo.MyEmployees
        where   EmployeeID=@EmployeeID
    end

    update @Result
    set Lvl = (select MAX(Lvl) from @Result)-Lvl+1
RETURN
END

然后只需应用PIVOT函数即可获得输出:

SELECT [1] AS Lvl1, [2] AS Lvl2, [3] AS Lvl3, [4] AS Lvl4
FROM 
(select a.EmployeeID,b.EmployeeID EID,b.Lvl
from    dbo.MyEmployees a cross apply
        dbo.GetTree(a.EmployeeID) b) p
PIVOT
(MIN (EID)
FOR Lvl IN
( [1], [2], [3], [4] )
) AS pvt