Вопрос

id  parent_id
1   0
2   0
3   2
4   0
5   1
6   0

Мне нужен запрос, который будет возвращать родительские строки (parent_id = 0), за которыми следуют его дочерние строки:

<Ол>
  • первый родитель
  • все дети первого родителя
  • второй родитель
  • все дети второго родителя
  • третий родитель
  • четвертый родитель
  • Ожидаемый результат: упорядочено по id

    id   parent_id
    -------------------------------------------
    1    0 (first parent)
    5    1     (all children of first parent)
    2    0 second parent
    3    2     (all children of second parent)
    4    0 third parent
    6    0 fourth parent
    

    Я могу использовать союз родителей, за которым следуют все дети Но это дает мне сначала родителей, потом детей. Мне нужен родитель и сразу его дети.

    Кто-нибудь может помочь?

    Это было полезно?

    Решение

    Это можно сделать с помощью двух временных таблиц и трех переменных.

    
    CREATE TABLE #Parents
    (
    RowId bigint identity(1,1),
    Id    bigint
    )

    CREATE TABLE #Results ( RowId bigint identity(1,1), Id bigint, ParentId bigint )

    DECLARE @Count1 bigint DECLARE @Count2 bigint DECLARE @ParentId bigint

    INSERT INTO #Parents SELECT Id FROM MyTable WHERE ParentId = 0 ORDER BY Id

    SET @Count1 = 0 SELECT @Count2 = MAX(RowId) FROM #Parents

    WHILE @Count1 < @Count2 BEGIN SET @Count1 = @Count1 +1 SELECT @ParentId = Id FROM #Parents WHERE RowId = @Count1 INSERT INTO #Results (Id, ParentId) VALUES (@Count1, 0) INSERT INTO #Results (Id, ParentId) SELECT ID, ParentId FROM MyTable WHERE ID = @Count1 ORDER BY Id END

    SELECT Id, ParentId FROM #Results ORDER BY RowId

    DROP TABLE #Results DROP TABLE #Parents

    Другие советы

    Если вы работаете в SQL Server 2005+, вы можете использовать рекурсивный CTE, следя за тем, чтобы в конце вы поддерживали поле, по которому можно было упорядочить.

    Попробуйте это:

    declare @t table (id int, parent_id int)
    insert @t
    select 1,0
    union all select 2,0
    union all select 3,2
    union all select 4,0
    union all select 5,1
    union all select 6,0
    ;
    
    with tree as (
    select t.*, convert(varbinary(max),t.id) as ordered
    from @t t
    where parent_id = 0
    union all
    select t.*, ordered + convert(varbinary(max),t.id)
    from tree base
     join
     @t t
     on t.parent_id = base.id
     )
    select * 
    from tree
    order by ordered
    ;
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top