You can do it this way:
UPDATE table_users
SET cod_user = (case when user_role = 'student' then '622057'
when user_role = 'assistant' then '2913659'
when user_role = 'admin' then '6160230'
end),
date = '12082014'
WHERE user_role in ('student', 'assistant', 'admin') AND
cod_office = '17389551';
I don't understand your date format. Dates should be stored in the database using native date and time types.
Answer from Gordon Linoff on Stack OverflowYou can do it this way:
UPDATE table_users
SET cod_user = (case when user_role = 'student' then '622057'
when user_role = 'assistant' then '2913659'
when user_role = 'admin' then '6160230'
end),
date = '12082014'
WHERE user_role in ('student', 'assistant', 'admin') AND
cod_office = '17389551';
I don't understand your date format. Dates should be stored in the database using native date and time types.
MySQL allows a more readable way to combine multiple updates into a single query. This seems to better fit the scenario you describe, is much easier to read, and avoids those difficult-to-untangle multiple conditions.
INSERT INTO table_users (cod_user, date, user_rol, cod_office)
VALUES
('622057', '12082014', 'student', '17389551'),
('2913659', '12082014', 'assistant','17389551'),
('6160230', '12082014', 'admin', '17389551')
ON DUPLICATE KEY UPDATE
cod_user=VALUES(cod_user), date=VALUES(date)
This assumes that the user_rol, cod_office combination is a primary key. If only one of these is the primary key, then add the other field to the UPDATE list.
If neither of them is a primary key (that seems unlikely) then this approach will always create new records - probably not what is wanted.
However, this approach makes prepared statements easier to build and more concise.
sql - Multiple Updates in MySQL - Stack Overflow
Can I Update Multiple Rows at Once?
Updating multiple columns and multiple rows with one MySQL query - Databases - SitePoint Forums | Web Development & Design Community
mysql - How can I UPDATE multiple ROWs in a Single Query with multiple WHERE clauses? - Database Administrators Stack Exchange
Videos
UPDATE mytable SET
fruit = CASE WHEN id=1 THEN 'orange' ELSE 'strawberry' END,
drink = CASE WHEN id=1 THEN 'water' ELSE 'wine' END,
food = CASE WHEN id=1 THEN 'pizza' ELSE 'fish' END
WHERE id IN (1,2);
Personally, using CASE WHEN THEN END looks clumsy.
You could code this using the IF function.
UPDATE mytable SET
fruit = IF(id=1,'orange','strawberry'),
drink = IF(id=1,'water','wine'),
food = IF(id=1,'pizza','fish')
WHERE id IN (1,2);
Give it a Try !!!
CAVEAT : CASE WHEN THEN END is only handy when dealing with multiple values (more than 2)
INSERT ... ON DUPLICATE KEY UPDATE
You will need to write very complicated conditions if you want to update more than two rows. In such a case you can use INSERT ... ON DUPLICATE KEY UPDATE approach.
INSERT into `mytable` (id, fruit, drink, food)
VALUES
(1, 'orange', 'water', 'pizza'),
(2, 'strawberry', 'wine', 'fish'),
(3, 'peach', 'jiuce', 'cake')
ON DUPLICATE KEY UPDATE
fruit = VALUES(fruit),
drink = VALUES(drink),
food = VALUES(food);
Yes, that's possible - you can use INSERT ... ON DUPLICATE KEY UPDATE.
Using your example:
INSERT INTO table (id,Col1,Col2) VALUES (1,1,1),(2,2,3),(3,9,3),(4,10,12)
ON DUPLICATE KEY UPDATE Col1=VALUES(Col1),Col2=VALUES(Col2);
Since you have dynamic values, you need to use an IF or CASE for the columns to be updated. It gets kinda ugly, but it should work.
Using your example, you could do it like:
UPDATE table SET Col1 = CASE id
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 4 THEN 10
ELSE Col1
END,
Col2 = CASE id
WHEN 3 THEN 3
WHEN 4 THEN 12
ELSE Col2
END
WHERE id IN (1, 2, 3, 4);
I've looked a little for this and it's not jumping out at me. Is it possible to update multiple rows at once with one query? For instance, can I turn these two queries:
queryStr = "update TEST_TBL set VAL1 = '1' WHERE SERIAL = 1;" queryStr = "update TEST_TBL set VAL1 = '1' WHERE SERIAL = 2;"
into something like this:
queryStr = "update TEST_TBL set VAL1 = '1' WHERE SERIAL = 1, SERIAL = 2;"
Obviously I know that won't work, but is there a way to kill two birds with one query?
Remarks
It is possible to update rows based on some condition. It is also possible to update multiple tables in one statement in MySQL.
Whether the latter is a good idea is debatable, though. The target tables would be joined together for the update, and when I say "joined", I mean it in a broader sense: you do not have to specify a joining condition, in which case theirs would be a cross join. In a cross join, when at least one of the tables has more than one row, the other table will inevitably have its rows duplicated in the joined set. If both have multiple rows, both will have them multiplied. Somewhat counter-intuitively, MySQL will still update each affected row just once, yet I would refrain from multi-table updates in such scenarios, even if solely because of the counter-intuitiveness.
Method 1
Anyway, moving on to your specific example, there is indeed no joining condition, only a filter on each table. You can specify those filters in the WHERE clause of the UPDATE. Now in order to select which value to update each column with, you can use a CASE expression. This is what the complete UPDATE statement might look like:
UPDATE
A, B
SET
A.col1 = 'abc',
A.col2 = 'xyz',
B.col1 = CASE B.col3
WHEN '1' THEN 'a'
WHEN '2' THEN 'b'
WHEN '3' THEN 'c'
END,
B.col2 = CASE B.col3
WHEN '1' THEN 'x'
WHEN '2' THEN 'y'
WHEN '3' THEN 'z'
END
WHERE
A.col3 = '1'
AND B.col3 IN ('1', '2', '3')
;
You can see that you have to repeat the same set of conditions in a CASE expression both for B.col1 and for B.col2. Is there a way to avoid that?
Method 2
Yes, there is. You can arrange the target values for B.col1 and B.col2 as well as the filtering values for B.col3 as a derived table and join it to B in the UPDATE clause, like this:
UPDATE
A,
B
INNER JOIN
(
SELECT 'a' AS col1, 'x' AS col2, '1' AS col3
UNION ALL
SELECT 'b', 'y', '2'
UNION ALL
SELECT 'c', 'z', '3'
) AS fltr ON B.col3 = fltr.col3
SET
A.col1 = 'abc',
A.col2 = 'xyz',
B.col1 = fltr.col1,
B.col2 = fltr.col2
WHERE
A.col3 = '1'
;
The join is also acting as a filter for B, so you can omit the one in the WHERE clause.
You can find a demo for each method at
db<>fiddle:
- Method 1
- Method 2
Better way
Finally, as have been remarked both at the beginning of this post and in the comments, you can have a separate UPDATE statement for each table. The result would be clear in intention both to the reader of your script and to the database engine. A simpler script enables the latter to have more options for optimisation.
Use either of the methods above for the table B update, but do both tables separately:
UPDATE
A
SET
A.col1 = 'abc',
A.col2 = 'xyz'
WHERE
A.col3 = '1'
;
UPDATE
B
INNER JOIN
(
SELECT 'a' AS col1, 'x' AS col2, '1' AS col3
UNION ALL
SELECT 'b', 'y', '2'
UNION ALL
SELECT 'c', 'z', '3'
) AS fltr ON B.col3 = fltr.col3
SET
B.col1 = fltr.col1,
B.col2 = fltr.col2
;
There is also another reason for splitting the updates in separate statements. Since for a single UPDATE statement the tables need to be joined, it is important that both tables have rows intended for the update. If one table has no matching rows, then, even if the other does, neither will be updated. This is because an empty set cross-joined to a non-empty set still results in an empty set.
So, the single UPDATE statement would have no rows to work with if at least one table had no rows matching the condition(s). That would not happen with separate UPDATEs, because each would work with its own table regardless of the contents of the other, therefore, absence of rows in one table would not affect the update of the other.
You can use below one for one table if you want to update many columns of one table.
UPDATE table
SET col1 = CASE WHEN col3 = 'name1' THEN 'a'
WHEN col3 = '2' THEN b
ELSE 0
END
, col2 = CASE WHEN col3 = '1' THEN 'b'
WHEN col3 = 'name2' THEN 'c'
ELSE ''
END
;