tags:

views:

201

answers:

7

I want to do all these update in one statement.

update table set ts=ts_1 where id=1
update table set ts=ts_2 where id=2
...
update table set ts=ts_n where id=n

Is it?

+1  A: 

Yes you can but that would require a table (if only virtual/temporary), where you's store the id + ts value pairs, and then run an UPDATE with the FROM syntax.
Assuming tmpList is a table with an id and a ts_value column, filled with the pairs of id value, ts value you wish to apply.

UPDATE table, tmpList
  SET table.ts = tmpList.ts_value
WHERE table.id = tmpList.id
  -- AND table.id IN (1, 2, 3, .. n)  
  -- above "AND" is only needed if  somehow you wish to limit it, i.e 
  -- if tmpTbl has more idsthan you wish to update

A possibly table-less (but similar) approach would involve a CASE statement, as in:

UPDATE table
  SET ts = CASE id
      WHEN 1 THEN 'ts_1'
      WHEN 2 THEN 'ts_2'
      -- ..
      WHEN n THEN 'ts_n'
  END
  WHERE id in (1, 2, ... n)  -- here this is necessary I believe
mjv
Is it performant?
The table-based form is quite performant; it is effectively more efficient than a series of UPDATE statements (but of course implies the creation of this temp table; if such a table doesn't exist, the time and effort to create it would largely offset the benefits of the single update). The CASE-based form is probably slightly less efficient than a series of UPDATE statements (it depends on the number of case/records updated.
mjv
I will choose the table-based solution,but how to use it to update two tables with the same column `ts`?
@unknown Not sure I understand you completely... Updating two tables at once (i.e. table1 and table, in addition to tmpList which itself isn't updated, only providing values for updates), would require that these two tables can be put in a one-to-one relationship (at least for the rows we are targetting for update. We'd then use SET table1.ts = tmpList.ts_value, table2.ts = tmpList.ts_value I believe this is possible (MySQL documentation), however I do not have direct experience with this myself. I typically address this type of situation with multiple updates...
mjv
@unknown. Maybe I should have asked this first ;-) Why are you so intent on only one update ?
mjv
`SET table1.ts = tmpList.ts_value, table2.ts = tmpList.ts_value` is to be followed by a `where` statement,which is hard to write...
The reason I'm so intent on only one update is simply because of performance:)
Hum... so you must be updating a lot of rows then, right ?
mjv
@mjv,yes.But I've never done this before...
A: 

ts_1, ts_2, ts_3, etc. are different fields on the same table? There's no way to do that with a single statement.

Roy Tang
Guess they should be read as strings
Tillebeck
+4  A: 

Use this:

UPDATE `table` SET `ts`=CONCAT('ts_', `id`);
Doug Neiner
No,you take it the other way round...
+1  A: 

Well, without knowing what data, I'm not sure whether the answer is yes or no.

It certainly is possible to update multiple rows at once:

update table table1 set field1='value' where field2='bar'

This will update every row in table2 whose field2 value is 'bar'.

update table1 set field1='value' where field2 in (1, 2, 3, 4)

This will update every row in the table whose field2 value is 1, 2, 3 or 4.

update table1 set field1='value' where field2 > 5

This will update every row in the table whose field2 value is greater than 5.

update table1 set field1=concat('value', id)

This will update every row in the table, setting the field1 value to 'value' plus the value of that row's id field.

Mike King
+1  A: 

You could do it with a case statement, but it wouldn't be pretty:

UPDATE table
SET ts = CASE id WHEN 1 THEN ts_1 WHEN 2 THEN ts_2 ... WHEN n THEN ts_n END
Rory
Seems you get me,but I'm caring about the performance?
I can't say for certain, but I would assume that CASE will make use of indexes on the id field. If you think about it, it's really just doing an equality check on the values and returning the matching value for the update. That said, profiling is always the best option for checking performance.
Rory
OOOH, adding WHERE id IN(1, 2, ... n) should help with performance. Sorry for only realising it now, it's 4:30am here ^_^
Rory
A: 

I think that you should expand the context of the problem. Why do you want/need all the updates to be done in one statement? What benefit does that give you? Perhaps there's another way to get that benefit.
Presumably you are interacting with sql via some code, so certainly you can simply make sure that the three updates all happen atomically by creating a function that performs all three of the updates.

e.g. pseudocode:

function update_all_three(val){
// all the updates in one function
}

The difference between a single function update and some kind of update that performs multiple updates at once is probably not a very useful distinction.

Tchalvak
A: 

generate the statements:

select concat('update table set ts = ts_', id, ' where id = ', id, '; ') 
from table

or generate the case conditions, then connect it to your update statement:

select concat('when ', id, ' then ts_', id) from table
Michael Buen