2015-05-20 96 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

謝謝指出這次我很幸運,因爲這是一個網絡應用程序,用於某些設備的某些設備的安裝,因此我可以完全控制服務器和客戶端;) –