Sql INSERT INTO语句复制行并自动递增非标识键ID列

Sql INSERT INTO语句复制行并自动递增非标识键ID列,sql,tsql,Sql,Tsql,给定一个有三列的表 ID(主键,非自动递增) GroupID 一些价值 我试图在语句中编写一个SQL INSERT,将具有一个GroupID的每一行复制到一个新的GroupID中 示例开始表: ID | GroupID | SomeValue ------------------------ 1 | 1 | a 2 | 1 | b 运行简单的INSERT INTO语句后的目标: ID | GroupID | SomeValue -------------

给定一个有三列的表

  • ID(主键,非自动递增)
  • GroupID
  • 一些价值
  • 我试图在语句中编写一个SQL INSERT,将具有一个GroupID的每一行复制到一个新的GroupID中

    示例开始表:

    ID | GroupID | SomeValue
    ------------------------
    1  |    1    |    a
    2  |    1    |    b
    
    运行简单的INSERT INTO语句后的目标:

    ID | GroupID | SomeValue
    ------------------------
    1  |    1    |    a
    2  |    1    |    b
    3  |    2    |    a
    4  |    2    |    b
    
    我想我可以做一些类似的事情:

    INSERT INTO MyTable
    (       [ID]
           ,[GroupID]
           ,[SomeValue]
    )
    (
    SELECT (SELECT MAX(ID) + 1 FROM MyTable)
           ,@NewGroupID
           ,[SomeValue]
     FROM MyTable
     WHERE ID = @OriginalGroupID
    )
    
    这会导致PrimaryKey冲突,因为它最终会多次重复使用相同的Max(ID)+1值

    在T-SQL WHILE语句中,只有一组INSERT语句具有递增的计数器值,这是我唯一的求助手段吗

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

    使用以下方法:

    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
    
    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
    。我还修复了WHERE子句中的错误(应该是
    GroupID=
    ,而不是
    ID=
    ):


    最好将子查询(尤其是一次性计算)移动到JOIN,这样性能会更好。如果在任何情况下其他答案都很慢,您可以使用mine@Michael:
    SQL Server
    足够聪明,可以只计算一次这样的表达式。@Quassnoi:从性能上看,我总是对数据投影中的子查询感到不安。无论如何,在联接部分中移动子查询不是火箭科学。安威,我将在SQLServer中分析它later@Quassnoi当前位置我建议您在这里发表关于正确性和速度的评论。你的文章很好:-)KudosIn SQL Server 2008我在尝试运行此命令时遇到一些错误。我发现第一个答案最容易理解,因为我有简单的SQL知识。不过,似乎我可以使用交叉连接完成相同的工作,我也会尝试一下。我也可以通过在OVER()语句中添加ORDER by子句来实现这一点,例如SELECT(ROW_NUMBER()OVER(ORDER by GroupID)+X.MaxID),感谢您指出缺少的内容。有趣的是,Postgres中没有参数的OVER()正在工作。如果OVER子句中的参数是可选的,我将稍后在SQL Server中尝试(我现在在OS X中)。这也给了我一个错误:
    排名函数“ROW\u NUMBER”必须有一个ORDER BY子句。
    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
    )