tags:

views:

16

answers:

1

Hello!

I'm trying to update two fields of several rows at once but I can't determine the right syntax to do so, except for doing so with one field update.

Each row is identified by an id, and therefore I'm using a CASE statement.

I have this table:

tbl_accounts(id_account, nation_id, group_id)



Now, the following query works for updating only one field:

UPDATE tbl_accounts SET nation_id = CASE id_account
WHEN 3 THEN 333
WHEN 5 THEN 555
ELSE nation_id END

The above will update the nation_id field of each corresponding row identified by its id_account.



And the following query doesn't work for updating two fields - please suggest a fix to the syntax. I'm trying to avoid using any SELECT/JOIN/etc':

UPDATE tbl_accounts SET nation_id = CASE id_account, group_id = CASE id_account
WHEN 3 THEN 3331, 3332
WHEN 5 THEN 5551, 5552
ELSE nation_id, group_id END



I could run this as two separate statements but I'm sure there's a way to combine the two into one.

Any help is highly appriciated!

+1  A: 

It sounds like you are looking for something like this:

UPDATE tbl_accounts
SET nation_id =
     CASE id_account
     WHEN 3 THEN 3331
     WHEN 5 THEN 5551
     ELSE nation_id
     END,
group_id =
     CASE id_account
     WHEN 3 THEN 3332
     WHEN 5 THEN 5552
     ELSE group_id
     END

But doing separate updates is a sensible solution in this situation. The above query will require checking every row in the table to see if it matches the condition. If you have an index on id_account (and presumably you do as it appears to be the primary key) then it will be very fast to update a single row.

UPDATE tbl_accounts SET nation_id = 3331, groupid = 3332 WHERE id_account = 3
UPDATE tbl_accounts SET nation_id = 5551, groupid = 5552 WHERE id_account = 5
Mark Byers
Mark hello! The above query doesn't work. Even when I remove the second "SET ...." clause it doesn't and the only fix, after removed this clause, is to remove the commas. So first, what is the correct syntax? And second, yes, 'id_account' is a primary key - what do you mean by performance terms? How comes two separate updates would work faster than one? Could you please shed some light? Oh and - I truely thank you for taking the time to inspect the case!
Poni
@Poni: Sorry, there were some syntax errors - hopefully fixed now. Which method is faster depends on the number of rows in your table and the latency of your connection, but assuming the table could contain a large number of rows, the two updates can be faster because it only requires two index lookups, whereas the combined version requires a full table scan and won't use the indexes.
Mark Byers
Hurray! (: Saw the "edited 1 min ago" and closely inspected, saw you've removed the second "SET" keyword, and it works! So now only one little clarification - now that you know that 'id_account' is a primary key - would it be faster to execute two updates or one such as the above? I thank you from the bottom of my heart! (:
Poni
Two updates it is then! I do not really understand how comes it will require a full table scan, but, for now I guess it'll suffice. Again - BIG THANK YOU!
Poni
Oh and, by two updates you mean like the code in the original post, correct?
Poni
@Poni: I've added my suggestion of the updates you could run instead to my post.
Mark Byers
Is that so? If it's a primary/unique field (id_account) wouldn't it automatically limit to one update? I'm definitely surprised. Are you sure that doing the updates compeletely separated (as in your answer edit) will result in faster operation on big table (~1m rows)?
Poni
@Poni: Which is faster - 1 query that makes one million comparisons, or 2 very fast queries with a bit of latency in between? And there's not just performance for this one query to consider - there's also the extra load (both disk and processor) you are putting on the server by making it perform one heavy query instead of two simple ones. But you don't have to take my word for it - you can test it for yourself to see what happens in each case.
Mark Byers
I see. Once again, thanks a lot Mark!
Poni