I have a MySQL table with 80 fields and I want to update all fields that contain a specified value. For example, I want to update the fields with item1
to the value 0
:
id_num field1 field2 field3 field4 field5
1 item1 item2 item3 item4 item5
2 item3 item3 item3 item4 item5
3 item2 item1 item3 item4 item5
4 item5 item4 item3 item2 item1
5 item1 item1 item3 item4 item5
6 item2 item2 item4 item4 item5
The result should be:
id_num field1 field2 field3 field4 field5
1 0 item2 item3 item4 item5
2 item3 item3 item3 item4 item5
3 item2 0 item3 item4 item5
4 item5 item4 item3 item2 0
5 0 0 item3 item4 item5
6 item2 item2 item4 item4 item5
I want to do it with a MySQL query. The problem I have is that with 80 fields, I would have to use 80 queries like:
update set field1=0 where field1=item1;
update set field2=0 where field2=item1;
And so on, which would be exhausting! :(
In an UPDATE
statement, the WHERE
clause determines which rows are updated. Here, you also need to determine which column to update; so the only use of the WHERE
clause would be to identify and filter out any rows where no columns at all need to change, ie:
UPDATE table
SET
...
WHERE field1 = "item1"
OR field2 = "item1"
OR field3 = "item1"
...;
But judging by the number of columns and what you're trying to do, there's no way you've got a covering index for such a query. And because they're all OR
conditions, you're not likely to be able to use even a single very selective index to prevent a full table scan. What that means is that the WHERE
clause is probably entirely useless for you here, and your UPDATE
is going to be slow on any reasonably large table.
So you can't filter rows, you can only choose which columns to SET
; but in any given row, you might have to set any column. So with SQL, you actually have to SET
every column; but apply a condition so that you only change the value when you want to. Use a CASE
expression for this:
UPDATE table
SET
field1 = CASE field1 WHEN "item1" THEN "0" ELSE field1 END,
field2 = CASE field2 WHEN "item1" THEN "0" ELSE field2 END,
field3 = CASE field3 WHEN "item1" THEN "0" ELSE field3 END,
...;
I'm using "item1"
and "0"
here just for consistency, since you haven't told us what the datatypes of these columns are. Use your own values, obviously.
Seeing your problem though, the question has to be asked: Why do you have this same "item1" in every column? You should have different sorts of data in each column, not repetitions of the same sort of data over and over again. There appear to be serious design issues with the table you're describing; you should seriously look into a redesign. The fact that you can't filter out any rows with your query is a big warning sign.
In many statements, you can do it like this.
UPDATE table
SET field1 = '0'
WHERE field1 = 'item1';
UPDATE table
SET field2 = '0'
WHERE field2 = 'item1';
...
UPDATE table
SET fieldN = '0'
WHERE fieldN = 'item1';
In one statement, you can do it like this.
UPDATE table
SET field1 = CASE WHEN field1 = 'item1'
THEN '0'
ELSE field1
END
, field2 = CASE WHEN field2 = 'item1'
THEN '0'
ELSE field2
END
...
, fieldN = CASE WHEN fieldN = 'item1'
THEN '0'
ELSE fieldN
END
;
However, I think this is another wrong question, and no literal answer will do good.
Id you need such a loop, your database design is probably wrong.
A column has to contain distinct value, not shared value among other columns.
Update : (a php solution) This PHP script will go through each column name and apply the query to it.
<?php
$result = mysql_query("SHOW COLUMNS FROM table ");
while ($row = mysql_fetch_assoc($result)) {
mysql_query("UPDATE table SET ".$row['field']." = '0' WHERE ".$row['field']." = 'item1'");
}
?>
If you have access to a web server with php, you can do this:
<?php
$connection = new mysqli( host, user, password, database );
// Skipping error checking
for ($i = 0; i < num_of_columns; i++) {
$connection->query( "UPDATE table SET field".i."=0 WHERE field".i."='item1'" );
}
?>
You should also consider database normalization, the act of making data like this manageable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.