Самый простой способ сделать рекурсивное самосоединение?

Голландия @Jonathan я видел, что Вы были провалены, но это - ОЧЕНЬ актуальный вопрос. Я читал некоторые сообщения вокруг межтруб, где люди, кажется, путают ASP.NET MVC платформа и MVC шаблон .

MVC в себя ШАБЛОН РАЗРАБОТКИ . Если все, что Вы ищете, является "разделением проблем", тогда можно, конечно, достигнуть этого с веб-формами. Лично, я - большой поклонник шаблон MVP в стандарте n-tier среда.

, Если Вы действительно хотите Полный контроль над своей разметкой в мире ASP.NET, тогда MVC, ramework для Вас.

93
задан DaveInCaz 21 September 2018 в 19:39
поделиться

4 ответа

WITH    q AS 
        (
        SELECT  *
        FROM    mytable
        WHERE   ParentID IS NULL -- this condition defines the ultimate ancestors in your chain, change it as appropriate
        UNION ALL
        SELECT  m.*
        FROM    mytable m
        JOIN    q
        ON      m.parentID = q.PersonID
        )
SELECT  *
FROM    q

Добавляя условие упорядочивания, вы можете сохранить порядок дерева:

WITH    q AS 
        (
        SELECT  m.*, CAST(ROW_NUMBER() OVER (ORDER BY m.PersonId) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN AS bc
        FROM    mytable m
        WHERE   ParentID IS NULL
        UNION ALL
        SELECT  m.*,  q.bc + '.' + CAST(ROW_NUMBER() OVER (PARTITION BY m.ParentID ORDER BY m.PersonID) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN
        FROM    mytable m
        JOIN    q
        ON      m.parentID = q.PersonID
        )
SELECT  *
FROM    q
ORDER BY
        bc

Изменяя условие ORDER BY , вы можете изменить порядок братьев и сестер.

100
ответ дан 24 November 2019 в 06:20
поделиться

Запрос Quassnoi с изменением для большой таблицы. Родители, у которых больше дочерних элементов, чем 10: Форматирование как str (5) row_number ()

WITH    q AS 
        (
        SELECT  m.*, CAST(str(ROW_NUMBER() OVER (ORDER BY m.ordernum),5) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN AS bc
        FROM    #t m
        WHERE   ParentID =0
        UNION ALL
        SELECT  m.*,  q.bc + '.' + str(ROW_NUMBER()  OVER (PARTITION BY m.ParentID ORDER BY m.ordernum),5) COLLATE Latin1_General_BIN
        FROM    #t m
        JOIN    q
        ON      m.parentID = q.DBID
        )
SELECT  *
FROM    q
ORDER BY
        bc

4
ответ дан 24 November 2019 в 06:20
поделиться

Используя CTE, вы можете сделать это следующим образом

DECLARE @Table TABLE(
        PersonID INT,
        Initials VARCHAR(20),
        ParentID INT
)

INSERT INTO @Table SELECT     1,'CJ',NULL
INSERT INTO @Table SELECT     2,'EB',1
INSERT INTO @Table SELECT     3,'MB',1
INSERT INTO @Table SELECT     4,'SW',2
INSERT INTO @Table SELECT     5,'YT',NULL
INSERT INTO @Table SELECT     6,'IS',5

DECLARE @PersonID INT

SELECT @PersonID = 1

;WITH Selects AS (
        SELECT *
        FROM    @Table
        WHERE   PersonID = @PersonID
        UNION ALL
        SELECT  t.*
        FROM    @Table t INNER JOIN
                Selects s ON t.ParentID = s.PersonID
)
SELECT  *
FROm    Selects
23
ответ дан 24 November 2019 в 06:20
поделиться

SQL 2005 или новее, CTE - это стандартный способ работы в соответствии с показанными примерами.

SQL 2000, вы можете сделать это с помощью UDF -

CREATE FUNCTION udfPersonAndChildren
(
    @PersonID int
)
RETURNS @t TABLE (personid int, initials nchar(10), parentid int null)
AS
begin
    insert into @t 
    select * from people p      
    where personID=@PersonID

    while @@rowcount > 0
    begin
      insert into @t 
      select p.*
      from people p
        inner join @t o on p.parentid=o.personid
        left join @t o2 on p.personid=o2.personid
      where o2.personid is null
    end

    return
end

(который будет работать в 2005 году, это просто не стандартный способ Тем не менее, если вы обнаружите, что это более простой способ работы, запустите его)

Если вам действительно нужно сделать это в SQL7, вы можете сделать примерно то же самое в sproc, но не можете выбрать из него - SQL7 не поддерживает UDF.

2
ответ дан 24 November 2019 в 06:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: