Sql 亲子关系

Sql 亲子关系,sql,sql-server,Sql,Sql Server,将数据从表1复制到表2。我的代码第一次工作,第二次在ParentId中不发送0 我的方案需要满足以下几点: 父子层次结构可以转到n级 父母可以有很多孩子 表2不应该有表1的Id和parentid数据,但它必须有自己的Id和parentid,但要记住两个表之间的父子关系必须匹配 -- Table 1 create table #Table1 ( Id int, ParentId int, Name varchar(50)) insert into #Table1 values(6,0, 'pers

将数据从表1复制到表2。我的代码第一次工作,第二次在ParentId中不发送0

我的方案需要满足以下几点:

  • 父子层次结构可以转到n级
  • 父母可以有很多孩子
  • 表2不应该有表1的Id和parentid数据,但它必须有自己的Id和parentid,但要记住两个表之间的父子关系必须匹配

    -- Table 1
    create table #Table1 (
    Id int, ParentId int, Name varchar(50))
    insert into #Table1 values(6,0, 'person1')
    insert into #Table1 values(7,0, 'person2')
    insert into #Table1 values(8,7, 'person3')
    insert into #Table1 values(9,6, 'person4')
    SELECT * from #Table1
    
    -- Table 2
    create table #Table2 (
    Id int IDENTITY(1,1) PRIMARY KEY, ParentId int, Name varchar(50))
    
    -- below code copy table1 data into table2 on the first try, the second time it does not take correct data.
    SET IDENTITY_INSERT #Table2 ON
    declare @MaxId int;
    select @MaxId=max(id)from #table2; 
    
    ;WITH NewIDs AS (
      SELECT OriginalID=T.Id, ReplacementID=ROW_NUMBER() OVER (ORDER BY T.ID ASC)
      FROM #Table1 AS T
    )
    INSERT INTO #Table2(Id, ParentId, Name)
      SELECT Id=N1.ReplacementID+coalesce(@MaxId, 0),
        ParentId=ISNULL(N2.ReplacementID, 0)+coalesce(@MaxId, 0),
        Name=T.Name
      FROM #Table1 AS T
      INNER JOIN NewIDs AS N1 ON T.Id=N1.OriginalID
      LEFT JOIN NewIDs AS N2 ON T.ParentId=N2.OriginalID
    
    SET IDENTITY_INSERT #Table2 OFF
    
    SELECT * from #Table1
    SELECT * from #Table2
    
  • **执行两次后,我得到了错误的结果(上一次是表1,下一次是表2)**

    我期望的结果是


    好的-我不能100%肯定这能解决您更广泛的业务逻辑问题,但它确实能产生您期望的结果。基本上,当您创建一个替换ID时,它必须从表中最后一个现有的ID开始,下面就是这样做的

    -- Table 1
    
    create table #Table1 (Id int, ParentId int, Name varchar(50))
    insert into #Table1 values(6,0, 'person1')
    insert into #Table1 values(7,6, 'person2')
    insert into #Table1 values(8,7, 'person3')
    insert into #Table1 values(9,7, 'person4')
    insert into #Table1 values(10,7, 'person5')
    insert into #Table1 values(11,9, 'person6')
    insert into #Table1 values(12,11, 'person7')
    insert into #Table1 values(13,7, 'person8')
    
    SELECT * from #Table1
    
    -- Table 2
    create table #Table2 (Id int IDENTITY(1,1) PRIMARY KEY, ParentId int, Name varchar(50))
    
    -- below code copy table1 data into table2 on first
    -- try, the second time it does not work.
    SET IDENTITY_INSERT #Table2 ON
    
    declare @MaxId int; -- Change Line 1
    select @MaxId = max(id) from #table2; -- Change Line 2
    
    ;WITH NewIDs AS
    (
      SELECT
        OriginalID = T.Id
        , ReplacementID = ROW_NUMBER() OVER (ORDER BY T.ID ASC)
        , ParentId
      FROM #Table1 AS T
    )
    INSERT INTO #Table2 (Id, ParentId, [Name])
      SELECT
        N1.ReplacementID + coalesce(@MaxId,0) -- Change Line 3
        , case when T.ParentId = 0 then 0 else ISNULL(N2.ReplacementID, 0) + coalesce(@MaxId,0) end -- Change Line 4
        , T.[Name]
      FROM #Table1 AS T
      INNER JOIN NewIDs AS N1 ON T.Id = N1.OriginalID
      LEFT JOIN NewIDs AS N2 ON T.ParentId = N2.OriginalID
    
    SET IDENTITY_INSERT #Table2 OFF
    
    SELECT * from #Table1
    SELECT * from #Table2
    

    好的-我不是100%确定这能解决您更广泛的业务逻辑问题,但它确实能产生您期望的结果。基本上,当您创建一个替换ID时,它必须从表中最后一个现有的ID开始,下面就是这样做的

    -- Table 1
    
    create table #Table1 (Id int, ParentId int, Name varchar(50))
    insert into #Table1 values(6,0, 'person1')
    insert into #Table1 values(7,6, 'person2')
    insert into #Table1 values(8,7, 'person3')
    insert into #Table1 values(9,7, 'person4')
    insert into #Table1 values(10,7, 'person5')
    insert into #Table1 values(11,9, 'person6')
    insert into #Table1 values(12,11, 'person7')
    insert into #Table1 values(13,7, 'person8')
    
    SELECT * from #Table1
    
    -- Table 2
    create table #Table2 (Id int IDENTITY(1,1) PRIMARY KEY, ParentId int, Name varchar(50))
    
    -- below code copy table1 data into table2 on first
    -- try, the second time it does not work.
    SET IDENTITY_INSERT #Table2 ON
    
    declare @MaxId int; -- Change Line 1
    select @MaxId = max(id) from #table2; -- Change Line 2
    
    ;WITH NewIDs AS
    (
      SELECT
        OriginalID = T.Id
        , ReplacementID = ROW_NUMBER() OVER (ORDER BY T.ID ASC)
        , ParentId
      FROM #Table1 AS T
    )
    INSERT INTO #Table2 (Id, ParentId, [Name])
      SELECT
        N1.ReplacementID + coalesce(@MaxId,0) -- Change Line 3
        , case when T.ParentId = 0 then 0 else ISNULL(N2.ReplacementID, 0) + coalesce(@MaxId,0) end -- Change Line 4
        , T.[Name]
      FROM #Table1 AS T
      INNER JOIN NewIDs AS N1 ON T.Id = N1.OriginalID
      LEFT JOIN NewIDs AS N2 ON T.ParentId = N2.OriginalID
    
    SET IDENTITY_INSERT #Table2 OFF
    
    SELECT * from #Table1
    SELECT * from #Table2
    


    @DaleBurrell在我看来像SQL Server语法。SQL Server@DaleBurrell发生错误是因为第一次插入数据时,数据不在那里。第二次插入相同的数据时,它已经存在,因此表2的主键阻止插入重复的值。有人试图创建一个替换id,我的图像试图解决重复问题,但我认为它从错误的表中获取行号。我添加了图像,请检查它们@需要第二个图像数据。我真的被这个查询卡住了。@DaleBurrell在我看来像SQL Server语法。SQL Server@DaleBurrell发生错误是因为第一次插入数据时,数据不在那里。第二次插入相同的数据时,它已经存在,因此表2的主键阻止插入重复的值。有人试图创建一个替换id,我的图像试图解决重复问题,但我认为它从错误的表中获取行号。我添加了图像,请检查它们@需要第二个图像数据。我真的被这个查询卡住了。现在唯一的问题是parentID在第二次执行时没有正确更新。是的,这就是我对您试图完成的任务的理解下降的原因。但希望现在你能看到什么是错误的,你有一个如何纠正它的想法?这可能很简单,只需将
    ParentId=ISNULL(N2.ReplacementID,0)
    更改为
    ParentId=ISNULL(N2.ReplacementID,0)+coalesce(@MaxId,0)
    没有一行等同于父id为0-可能应该是1?所有剩余的父id都存在于id列中-0不存在。是的,你是对的,没有id有0,但我的要求是这样的。唯一的parentid可以有0。我不明白-你是说parentid 0应该保持为0而不被更改吗?现在唯一的问题是parentid在第二次执行时没有正确更新。是的,这就是我对你试图实现的目标的理解下降的原因。但希望现在你能看到什么是错误的,你有一个如何纠正它的想法?这可能很简单,只需将
    ParentId=ISNULL(N2.ReplacementID,0)
    更改为
    ParentId=ISNULL(N2.ReplacementID,0)+coalesce(@MaxId,0)
    没有一行等同于父id为0-可能应该是1?所有剩余的父id都存在于id列中-0不存在。是的,你是对的,没有id有0,但我的要求是这样的。唯一的parentid可以有0。我不明白-您是说parentid 0应该保持为0而不被更改吗?