2011-03-15 23 views
1

我有類似更新基於斷電流值(在MySQL)的場

CREATE TABLE `mytable` (
    `ID` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `Time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    KEY `time` (`Time`), 
) ENGINE=MyISAM AUTO_INCREMENT=2373485 DEFAULT CHARSET=latin1 

我曾與夏令時一個奇怪的問題表,現在我需要通過更新與編號2370144行2373391,因此Time的值比其當前值小六個小時。

我可以

SELECT * FROM mytable WHERE ID >= 2370144 AND ID <= 2373391 

選擇受影響的行,以使新的時間戳爲六小時內小於舊值如何更新這些條目?

回答

1

我認爲這會工作

UPDATE mytable SET Time = date_sub(Time, INTERVAL 6 HOUR) WHERE id BETWEEN 2370144 AND 2373391; 
1
UPDATE mytable 
SET `Time` = (`Time` - INTERVAL 6 HOUR) 
WHERE ID >= 2370144 
AND ID <= 2373391 

擴展在這一點,在可行的情況我通常會運行一個SQL查詢來生成包含每行一個UPDATE語句.sql文件,然後執行SQL文件更新行。由於您只更新約3,000行,因此對您而言應該是可行的。

這轉儲和裝載方式有幾個好處:

  • 您可以將SQL腳本保存爲你改變什麼的 審計記錄。
  • 您可以在SQL腳本中包含ID和時間 值。這樣,如果 您意外運行腳本更多 比一旦您不最終更改 值不正確。對於 例如,如果你跑了我原來的 更新兩次的數值會結束 6小時太低,但如果你使用 轉儲並加載方式和運行 腳本兩次,第二次它 不會更改記錄,因爲 where子句將不再匹配。

這裏的轉儲並加載方法的一個例子:

select concat('update mytable set `Time` = ''', 
    `Time` - interval 6 hour, 
    ''' where id = ', 
    id, 
    ' and `Time` = ''', 
    `Time`, 
    ''';') as sql_stmt 
into outfile '/tmp/mytable.update.dstfix.20110315.sql' 
from mytable 
WHERE ID >= 2370144 
AND ID <= 2373391; 

\. /tmp/mytable.update.dstfix.20110315.sql 
+0

沒試過你的方法,但我想它的工作原理,以及。感謝您的迴應。 – Pat 2011-03-15 20:54:01

+0

沒問題。我只是擴大了我的答案,給你一個更安全的解決方案。 – 2011-03-15 21:13:21