tags:

views:

45

answers:

4

I have a table posts with the column published, which is either 0 (unpublished) or 1 (published). Say I want to make all the published posts into unpublished posts and all the unpublished posts into published posts. I know that running

UPDATE posts SET published = '1' WHERE published = '0';
UPDATE posts SET published = '0' WHERE published = '1';

will end up turning all my posts into published posts. How can I run these queries in the mysql command line so that it truly "reverse" the values, as opposed to the mistake outlined above?

Thanks

EDIT: assume the data types are strings. I know ints/bools are a much better way to do this, but I'm working with strings, and changing the schema is not an option.

+2  A: 

If this seems really difficult, you haven't been thinking about it enough.

UPDATE posts SET published = 1 - published;

Should do it, or some other solutions (such as using XOR, or CASE).

MarkR
What if I'm working with strings and not INTS/Bools?This isn't the actual schema I'm using, I changed it to protect the innocent. I should have used strings in my question, but the concept is still the same: changing column A to the value of column B and vice versa, without turning everything into the value of a single column.
CASE is probably the most general solution. I think changing A to B and B to A is a different problem, one which I don't immediately know the answer to (without assigning a temporary variable). I'm not completely sure of the evaluation order in mysql UPDATE statements, but I have a feeling that after you've set a column, using it in an expression later in the same update statement uses the new value, not the old one.
MarkR
+2  A: 

For strings - you can use any expression in the SET clause.

UPDATE posts SET published = IF(published = "1", "0", "1");

CASE version, thanks OMG Ponies:

UPDATE posts SET published = CASE published WHEN "1" THEN "0" ELSE "1" END;

In both versions, if published IS NULL, it will set to "1" as any comparison with NULL is false.

rjh
OMG Ponies
It looks like CASE is the most useful. Could you further explain that IF() function. The order of arguments doesn't yet make sense to me.
@user94154: The first argument is the statement to evaluate. The second is the value returned if the statement is true, and the third is if the statement is false.
OMG Ponies
+2  A: 

Use:

UPDATE posts
   SET published = CASE 
                     WHEN published IS NULL THEN NULL
                     WHEN published = '1' THEN '0'
                     ELSE '1' 
                   END
OMG Ponies
Case is a good general solution; mine only worked with integers 0 and 1
MarkR
This did exactly what I needed. Thanks so much!
A: 

What do you guys think of this:

UPDATE posts SET published = 'A1' WHERE published = 'A';
UPDATE posts SET published = 'B' WHERE published = 'A';
UPDATE posts SET published = 'A' WHERE published = 'A1';

EDIT: this isn't remotely correct