MYSQL 處理批量更新數據的一些經驗
摘要 很多人都會碰到有一堆數據需要更新,但是他們所需要更新的數值往往都不盡相同,貌似就只能用FOR循環去更新了嗎?我就不信......
首先,我們需要了解下MYSQL CASE EXPRESSION 語法。
手冊傳送門:http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html
有關這個的討論的stackoverflow:http://stackoverflow.com/questions/29205842/can-mysql-case-expression-running-well-with-the-same-when-condition
看完以上,你就會少走很多彎路。
我有很多條記錄需要更新不同的值怎么辦呢?
我們可以這樣:
UPDATE activity SET number = CASE WHEN aid = 45 THEN number + 1 WHEN aid = 43 THEN number + 1 END WHERE aid IN (45, 43)
或者這樣:
UPDATE activity SET number = CASE aid WHEN 45 THEN number + 1 WHEN 43 THEN number + 1 END WHERE aid IN (45, 43)
這個語法和程序語言中的switch case控制流差不多意思,但是有幾點需要注意:
ex1:
UPDATE activity SET number = CASE WHEN aid = 45 THEN number + 1 WHEN aid = 43 THEN number + 1 WHEN aid = 45 THEN number + 3 WHEN aid = 49 THEN number + 1 WHEN aid = 45 THEN number + 1 END WHERE aid IN (45, 43,49)
看到了嗎?會不會有人一開始像我一樣認為aid=45 的number+5的?放心....aid=45 的number就僅僅加了1.換句話說也就是第一個when aid=45 then number+1執行了!第二次再碰到when aid=45的時候,系統就認為這個條件已經執行過了,后門的aid=45就直接跳過不執行的了,但是中間的aid=43 aid=49的還是可以正常執行的!
也就是說,所有相同的when條件就只執行第一次!
ex2:
UPDATE activity SET number = CASE aid WHEN 45 THEN number + 1 WHEN 43 THEN number + 1 END
這個你覺得會怎么樣?貌似和上面的沒啥不同啊?這個就糟糕了.....如果沒有約束條件,那么aid=45 aid=43的number+1以外,別的aid都會set number=null.....這就好像你用簡單版的update set沒有寫where條件來約束范圍的情況一樣。小心小心.....
這里只討論了如何使用CASE EXPRESSION 來進行批量更新.....
無論是insert 或者update,批量處理總是要比一個個來的要效率,當然這里指的是一般情況下的使用。最后來看看在PHP下使用批量更新的處理方案:
/* $aids is an array which the key is the activity's primary key and the value is the activity's number. example $aids = array('45'=>4,'43'=>1...) In the array,i combine all the same aid to one element.so one aid can not be used twice by the case expression.And all the number are total number. */ $sql = 'update huodong_activity set applynumber = case '; $aids_str = implode(',',array_keys($aids)); foreach($aids as $k=>$v){ $sql .= sprintf(' when aid = %d then applynumber-%d',$k,$v); } $sql .= ' END WHERE aid IN ('.$aids_str.') '; $db->query($sql);
注意語句鏈接要適當給予空格....