关于复制行并自动递增非标识键ID列的sql:INSERT INTO语句

INSERT INTO statement that copies rows and auto-increments non-identity key ID column

给定一个包含三列的表格

  • ID(主键,非自动递增)
  • 组ID
  • 某个值
  • 我正在尝试编写一个 SQL INSERT INTO 语句,该语句会将具有一个 GroupID 的每一行复制到一个新的 GroupID 中。

    示例起始表:

    1
    2
    3
    4
    ID | GroupID | SomeValue
    ------------------------
    1  |    1    |    a
    2  |    1    |    b

    运行简单的 INSERT INTO 语句后的目标:

    1
    2
    3
    4
    5
    6
    ID | GroupID | SomeValue
    ------------------------
    1  |    1    |    a
    2  |    1    |    b
    3  |    2    |    a
    4  |    2    |    b

    我想我可以这样做:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    INSERT INTO MyTable
    (       [ID]
           ,[GroupID]
           ,[SomeValue]
    )
    (
    SELECT (SELECT MAX(ID) + 1 FROM MyTable)
           ,@NewGroupID
           ,[SomeValue]
     FROM MyTable
     WHERE ID = @OriginalGroupID
    )

    这会导致主键冲突,因为它最终会多次重复使用相同的 Max(ID) 1 值。

    我是否只能求助于具有递增计数器值的 T-SQL WHILE 语句中的一堆 INSERT 语句?

    我也没有选择将 ID 转换为自动递增的 Identity 列,因为这会破坏我没有源代码的代码。


    添加行号而不是 + 1。我还修复了您的 WHERE 子句中的错误(应该是 GroupID =,而不是 ID =):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    INSERT INTO MyTable
    (       [ID]
           ,[GroupID]
           ,[SomeValue]
    )
    (
        SELECT
           (SELECT MAX(ID) FROM MyTable) + ROW_NUMBER() OVER (ORDER BY GroupId),
           @NewGroupID,
           [SomeValue]
        FROM MyTable
        WHERE GroupID = @OriginalGroupID
    )

    使用这个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    INSERT INTO MyTable
    (       [ID]
           ,[GroupID]
           ,[SomeValue]
    )    
     SELECT ROW_NUMBER() OVER() + X.MaxID
           ,@NewGroupID
           ,[SomeValue]
     FROM MyTable
     CROSS JOIN (SELECT MAX(ID) AS MaxID FROM MyTable) X
     WHERE GroupID = @OriginalGroupID


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    WITH    q AS
            (
            SELECT  *,
                    (
                    SELECT  MAX(id)
                    FROM    mytable
                    ) + ROW_NUMBER() OVER () AS nid
            FROM    mytable
            WHERE   groupID = 1
            )
    INSERT
    INTO    mytable (id, groupid, somevalue)
    SELECT  nid, 2, somevalue
    FROM    q