UPDATE table SET x = :x, y = :y, z = IF(x <> :x, NOW(), z);
IF(oldX <> :newX) THEN NOW() ELSE NO CHANGE;
MySQL does not support the standard on this:
The second assignment in the following statement sets col2 to the current (updated) col1 value, not the original col1 value. The result is that col1 and col2 have the same value. This behavior differs from standard SQL.
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
So, the following works in a simple example in SQL Fiddle:
UPDATE table SET x = if (@x := x, :x, :x), y = :y, z = IF(x <> @x, NOW(), z);
It should also work if you reverse the order:
UPDATE table SET z = IF(x <> :x, NOW(), z), x = :x, y = :y;
The documentation says that single table updates are "generally" processed in lexical order.