2015-05-20 78 views
1

我有一个10列和24行可以存储值或可以= 0的表。它们被称为msg1,msg2 ...高达msg10。 我正在写一个查询来更新此表,而不是任何字段中的特定值。mysql缩水where子句

所以我写了(59是一个测试值,将被PHP dinamically更新):

UPDATE schedule SET msg1='0' WHERE msg1='59' OR SET msg2='0' WHERE msg2='59'.... 
OR SET msg10='0' WHERE msg10='59' 

这显然是不工作的,反正是我所见过的低效率的查询之一。所以问题是:什么是迭代遍历所有行和列的巧妙方式,寻找特定值(即59),如果是,则将其更改为0?

我知道我可以使用for循环来做到这一点,但最终每次都会做24个查询......效率也不高!

+0

'这显然不起作用,无论如何将是效率不高的查询之一',如果查询不起作用,你怎么知道它的效率是否低于时间? –

+0

看看使用“案例”,它相当方便... https://dev.mysql.com/doc/refman/5.0/en/case.html – dbinns66

+0

看到正常化。见正常化。见正常化。 – Strawberry

回答

4

你将不得不引用每一列。我只是对表进行全面扫描,然后更新每一行。索引不会帮助,不需要WHERE子句。假设这些列是字符,请在值的周围使用单引号。如果这些是数字,您可以省略单引号。

UPDATE schedule 
    SET msg1 = IF(msg1='59','0',msg1) 
    , msg2 = IF(msg2='59','0',msg2) 
    , msg3 = IF(msg3='59','0',msg3) 
    , ... 

如果你想添加一个WHERE条款(这是不是真的需要),那么您就SET子句之后将其添加...

WHERE msg1='59' 
    OR msg2='59' 
    OR msg3='59' 

我我很想写这个陈述,所以我只需要指定'59''0'这个值,就像这样:

UPDATE schedule s 
CROSS 
    JOIN (SELECT '59' AS oldval, '0' AS newval) v 
    SET s.msg1 = IF(s.msg1=v.oldval,v.newval,s.msg1) 
    , s.msg2 = IF(s.msg2=v.oldval,v.newval,s.msg2) 
    , s.msg3 = IF(s.msg3=v.oldval,v.newval,s.msg3) 
+0

你的第三个例子非常有趣。由于我需要用php变量替换'59',所以非常方便。从未使用CROSS JOIN,谢谢!我学到了一些新东西! –

+0

@LelioFaieta:注意:对于内联视图中的SELECT列表中的文字,我们可能遇到隐含的字符集转换引发“不可强制”错误的问题,例如,如果客户端字符集是utf8并且我们正在比较的表列)(内联视图正在物化为“派生表”,所以列会得到一个字符集,如果遇到这个问题,有办法解决这个问题......'SELECT _latin1'59''。 – spencer7593

+0

谢谢指出这次我很幸运,因为这是一个网络应用程序,用于某些设备的某些设备的安装,因此我可以完全控制服务器和客户端;) –