Given a table that has three columns
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.
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) .
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.
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.
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.
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
)
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With