James P. Wright
James P. Wright

Reputation: 9131

SQL Copy Row for a list, change one column value

I need to duplicate a row a couple thousand times. I need to change one column from the copied row based on a list of ids. Psuedo-code:

INSERT INTO MyTable (TabID, Other Columns)
VALUES (TabID = (SELECT TabID FROM OtherTable WHERE ParentID = 1), Other Columns)

Is this doable?

Upvotes: 1

Views: 5378

Answers (6)

Echilon
Echilon

Reputation: 10264

Cross joins can be difficult to get your head around. I had a similar problem on a permissions table. I wanted to copy user 1's permissions to a new user (10):

UserID      ItemID     
1           CBE17 
1           184AB
1           459FA 
1           3856D
1           A261D

You could add more columns if needed.

INSERT INTO UserPermissions (UserID, ItemID)
   SELECT 
      12, 
      ItemID 
   FROM UserPermissions WHERE RoleID = 1

Upvotes: 0

Vland
Vland

Reputation: 4272

I had to solve a similar problem with my 2 tables: User and UserCustomSetting. I wanted every user to inherit the settings of the "Default" user record.

I solved with a simple CROSS JOIN. This is my T-SQL query

DECLARE @Username VARCHAR(100) = 'DefaultUser';

--get default UserID
DECLARE @UserID INT = (SELECT UserID FROM [User] WHERE [User].Username = @Username)

-- delete previous settings (except default user)
DELETE FROM UserCustomSetting WHERE UserCustomSetting.UserID <> @UserID

-- insert new settings for all users, copy them from the default user
INSERT INTO UserCustomSetting                               
SELECT u.UserID, ucs.SettingKey, ucs.Value
FROM [User] AS u
CROSS JOIN UserCustomSetting AS ucs 
WHERE ucs.UserID = @UserID
AND u.Username <> @Username

Upvotes: 0

Newfave
Newfave

Reputation: 196

I'll note that using the GO statement with your query, you can do things like GO 2000 and your statement will be executed 2000 times. You can insert 2000 rows that way easily. That might at least help you test and plan your solution.

Example:

CREATE TABLE #TableExample(thisid int IDENTITY(1,1) , thiscol varchar(1))

INSERT INTO #TableExample ( thiscol ) VALUES  ('x')
GO 2000 -- INSERT Statement will execute 2000 times.


DROP TABLE #TableExample

Can you explain why you need to duplicate the rows and what they will be used for? If you share those assumptions, the feedback you get might lead to changing those assumptions and ultimately lead to a better solution.

Upvotes: 0

Michael Petrotta
Michael Petrotta

Reputation: 60972

How do you want to change Tab1? If you wanted to increment it, for sake of argument, you could do this:

declare int @i
set @i = 0
while (@i < 1000)
begin
    INSERT INTO MyTable (TabID, col1, col2)
    SELECT TabID+1, col1, col2
    FROM OtherTable
    WHERE ParentID = 1 -- assuming only one row with that ID

    set @i = @i+1
end

A cleaner, neater way is to create a numbers table (code below untested):

DECLARE @numbers TABLE (n int)
declare int @i
set @i = 0
while (@i < 1000)
begin
    INSERT INTO @numbers (n) VALUES (i)
    set @i = @i+1
end

INSERT INTO MyTable (TabID, col1, col2)
SELECT TabID+1, col1, col2
FROM OtherTable
CROSS JOIN @numbers n
WHERE ParentID = 1 -- assuming only one row with that ID

Upvotes: 1

DOK
DOK

Reputation: 32851

Do you have access to using SQL Server CLR? You could write your code in C# or VB using the usual loops and get this done quite handily.

In the absence of CLR, you could compose a giant SQL string in just about any coding language, and send it to the database. That way, you could use the usual looping (for loop, do loop, foreach).

Upvotes: 1

Quassnoi
Quassnoi

Reputation: 425863

INSERT
INTO    mytable
SELECT  othertable.tabid, mytable.othercolumn
FROM    mytable
CROSS JOIN
        othertable
WHERE   othertable.parentid = 1

This implies there is only one record with parentid = 1 in othertable (otherwise your subselect would fail)

Upvotes: 1

Related Questions