t-sql: получить один ряд с родителями, детьми, внуками ... n детьми - PullRequest
1 голос
/ 28 марта 2011

У меня есть таблица с 2 столбцами: ID, ParentID

Я хочу создать новую таблицу / представление, чтобы каждая строка включала всех детей на всех уровнях для определенных родителей ...

например:

ParentID  Level_1  Level_2  Level_3 ... Level_n

это означает, что parentID является родителем Level_1, который является родителем уровня 2, который является родителем level_3 и т. Д. *

Мне нужно сделать это без рекурсии, чтобы не было возможности переполнения стека ...

в T-SQL есть функция с именем @@rowcount, которая возвращает строки, которые я получил в последнем выборе, поэтому, возможно, я смогу использовать его внутри цикла while или что-то в этом роде ...

вопрос в том, как узнать, сколько столбцов нужно построить в начале? Любая идея, как получить доступ к этой проблеме?

Ответы [ 2 ]

1 голос
/ 28 марта 2011

То, что вы пытаетесь получить, это сводная таблица, но, на мой взгляд, эта задача не относится к базе данных.Я бы предпочел получить результирующий набор со строками и повернуть их «извне».

Чтобы достичь того, что я описал, в SQL Server 2005+ вы можете использовать общее табличное выражение ( здесь вы можете найтипример , тогда как SQL Server 2000 требует немного другого подхода.

Примечание : хотя вы написали «нет рекурсии, поэтому нет шансов переполнения стека», вам все равно придется проецироватьсебя из бесконечных циклов. Я лично использую рекурсию и устанавливаю для нее максимальную «глубину», когда рекурсия пытается пройти «глубже», чем предел, я прекращаю ее и возвращаю ошибку.

0 голосов
/ 28 марта 2011

Это можно решить, создав функцию 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...