Reputation: 1994
I need to update a single column over a thousand rows in the database. Normally when I need to do this, I'll do the following:
UPDATE [table] SET DATA="FOO" WHERE ID=23;
UPDATE [table] SET DATA="ASD" WHERE ID=47;
UPDATE [table] SET DATA="FGH" WHERE ID=83;
UPDATE [table] SET DATA="JKL" WHERE ID=88;
UPDATE [table] SET DATA="QWE" WHERE ID=92;
UPDATE [table] SET DATA="BAR" WHERE ID=97;
I feel like there should be a way to do this easily, but after searching around online, I cannot find a solution.
What I was hoping for was this:
-- THIS DOES NOT WORK
UPDATE [table]
SET DATA=("FOO", "ASD", "FGH", "JKL", "QWE", "BAR")
WHERE ID=(23, 47, 83, 88, 92, 9);
An important piece of information to note is that I am always setting one column, the same column across a specific set of rows.
Does anyone know the best way to do this?
Upvotes: 4
Views: 85815
Reputation: 27842
Sql Server
UPDATE t1
set DATA = derived1.NewValue
From
[table] t1 join
(
Select 'Foo' as NewValue, 23 as MyId
union all Select 'ASD' as NewValue, 47 as MyId
union all Select 'FGH' as NewValue, 83 as MyId
) as derived1
on t1.ID = derived1.MyId
Note, you can hydrate/populate "derived1" anyway you'd like. As long as the result set is the correct rows of "NewValue" and "MyId".
Upvotes: 2
Reputation: 350009
You could use the MERGE
statement which is in the SQL:2003 standard and available in Transact-SQL since SQL Server 2008:
MERGE mytable
USING (VALUES (23, 'FOD'),
(47, 'ASD'),
(83, 'FGH'),
(88, 'JKL'),
(92, 'QWE'),
( 9, 'BAR')) AS pairs(id2, data2)
ON id = id2
WHEN MATCHED
THEN UPDATE SET data = data2
The USING
clause allows to specify a derived table using a table value constructor (See example under point D on that page).
Alternatively, the more commonly implemented SQL:92 standard syntax to do this would be:
UPDATE mytable
SET data =
CASE id
WHEN 23 THEN 'FOD'
WHEN 47 THEN 'ASD'
WHEN 83 THEN 'FGH'
WHEN 88 THEN 'JKL'
WHEN 92 THEN 'QWE'
WHEN 9 THEN 'BAR'
END
WHERE id IN (23, 47, 83, 88, 92, 9);
The obvious downside is that you end up specifying the id values twice. You could do without the WHERE
clause and add ELSE data
in the CASE
construct, but then you would actually update all rows, which is inefficient and may have undesired side-effects (via triggers).
Upvotes: 11
Reputation: 1381
You can actually do it using insert into ...on duplicate key update
insert into [table](ID,DATA)
values(23,'FOO'),(47,'ASD'),(54,'DSF')..,
on duplicate key update DATA=values(DATA)
Upvotes: 3
Reputation: 28890
one way i could think of is join..The way you are trying to update wont scale
---insert your updates in a table like below every time you want to update data.
create table #test
(
data varchar(2),
id int
)
insert into #test
select 'abc',1
union all
select 'cde',2
now you update your main table like below
update mt
set mt.data=t.data
from maintable mt
join
#test t
on t.id=mt.id
Upvotes: 1
Reputation: 50019
I'm assuming that you are in MySQL. You can use a combination of "Field" and "Elt" functions to do what you need in a single query (beside the CASE WHEN THEN WHEN THEN WHEN THEN WHEN THEN WHEN THEN WHEN THEN WHEN THEN END
or IF(<condition>,<output>,if(<condition2>,<output2>, if()))
methods.
UPDATE [table] SET DATA=ELT(FIELD(ID,
13, 14, 15, 16, 17, 18, 19),'FOO', 'ASD', 'FGH', 'JKL', 'QWE', 'BAR');
This is similar to the DECODE()
function in Oracle, which I wish had counterparts in other DBMS's.
Upvotes: 4