Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

sql

tsql

Given a table that has three columns

  1. ID (Primary Key, not-autoincrementing)
  2. GroupID
  3. SomeValue

I am trying to write a single SQL INSERT INTO statement that will make a copy of every row that has one GroupID into a new GroupID.

Example beginning table:

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

Goal after I run a simple INSERT INTO statement:

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

I thought I could do something like:

INSERT INTO MyTable
(       [ID]
       ,[GroupID]
       ,[SomeValue]
)
(
SELECT (SELECT MAX(ID) + 1 FROM MyTable)
       ,@NewGroupID
       ,[SomeValue]
 FROM MyTable
 WHERE ID = @OriginalGroupID
)

This causes a PrimaryKey violation since it will end up reusing the same Max(ID)+1 value multiple times as it seems.

Is my only recourse to a bunch of INSERT statements in a T-SQL WHILE statement that has an incrementing Counter value?

I also don't have the option of turning the ID into an auto-incrementing Identity column since that would breaking code I don't have source for.

like image 837
AmoebaMan17 Avatar asked May 12 '10 16:05

AmoebaMan17


People also ask

How can insert auto increment value in SQL query?

The MS SQL Server uses the IDENTITY keyword to perform an auto-increment feature. In the example above, the starting value for IDENTITY is 1, and it will increment by 1 for each new record. Tip: To specify that the "Personid" column should start at value 10 and increment by 5, change it to IDENTITY(10,5) .

How can I get auto increment value after insert?

To obtain the value immediately after an INSERT , use a SELECT query with the LAST_INSERT_ID() function. For example, using Connector/ODBC you would execute two separate statements, the INSERT statement and the SELECT query to obtain the auto-increment value.

What is an identity column in insert statements?

An identity column contains a unique numeric value for each row in the table. Whether you can insert data into an identity column and how that data gets inserted depends on how the column is defined.

Can you insert into an identity column?

By default, it's not possible to manually insert a value directly into an identity column value, but identity values can be manually entered if you turn on a session option.


3 Answers

Instead of + 1, add the row number. I also fixed the error in your WHERE clause (should be GroupID =, not ID =):

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
)
like image 186
Mark Byers Avatar answered Sep 27 '22 19:09

Mark Byers


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
like image 34
Quassnoi Avatar answered Sep 27 '22 19:09

Quassnoi


Use this:

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
like image 36
Michael Buen Avatar answered Sep 27 '22 18:09

Michael Buen