2012-06-12 50 views
1

我想在更新單個項目的位置,例如更新項目從列表中的位置:MySQL的情況時將無法正常工作

  1. 物品1
  2. ITEM2
  3. 項目3
  4. ITEM4
  5. ITEM5

移動ITEM5位置2將更新列表:

  1. ITEM1
  2. ITEM5 < < 新位置
  3. ITEM2 < < [向下移動一個]
  4. 項目3 < < [向下移動一個]
  5. ITEM4 < < [ 向下移動一個]

UPDATE subjects SET 
position = (CASE WHEN position < {$position} THEN position + 1 
WHEN position > {$position} THEN position - 1 else position END CASE) 
WHERE position <= position AND position >= {$position}; 

此SQL查詢不起作用。然而,我也想要做的是IF位置< {$ position}然後使用WHERE子句作爲它現在的位置,但是如果位置> {$ position},我希望< =和> = swap (這將隨後允許移動位置時向上或向下的名單

+0

你得到的錯誤是什麼? – Cfreak

+0

我認爲它確實執行,但是他對迴應不滿意。至少,我是這麼讀的。 – Digitalis

+0

數據庫查詢失敗:您的SQL語法出錯;檢查對應於您的MySQL服務器版本的手冊,以便在第3行的'CASE)WHERE position <= position AND position> = 1時使用正確的語法 – Justin

回答

0

如果positionUNIQUE約束,則需要2個或3個步驟,由於非標準的方式,MySQL的UPDATE語句的工作方式更新:

UPDATE subjects 
    SET position = -67    --- an impossible value 
WHERE position = 5 ; 

UPDATE subjects 
    SET position = position + 1  
WHERE position BETWEEN 2 AND 5 
ORDER BY position DESC ; 

UPDATE subjects 
    SET position = 2 
WHERE position = -67 ; 
2

我不確定WHERE position <= position的要求是什麼,因爲position將始終等於position在同一行...

我也看不到你的update語句只能用一個參數工作,當然你需要該項目的當前位置來更新以及移動它的位置?

假設以上是正確的,你可以按如下方式(使用2個參數$new新位置和$current當前位置)寫你的查詢:

UPDATE subjects 
SET  position = CASE WHEN position = {$current} THEN {$new} 
         ELSE position + SIGN({$current} - {$new}) 
        END 
WHERE position BETWEEN LEAST({$current}, {$new}) AND GREATEST({$current}, {$new}) 

的前提是現值之間只排並且需要更新where子句所涵蓋的新值。接下來,更新語句使用SIGN函數來確定移動是上移還是下移,從當前位置添加或移除1(除了要用新位置更新的移動行)

工作例

http://sqlfiddle.com/#!2/99c64/1

我不得不做的架構部分更新,所以你不能看到表已經究竟是如何在SQL小提琴改變,但是你應該從結果中看到,具有值「3」的行已經從位置3移動到位置8,並且從8到4的所有位置都被移位了向下一個。在下面的小提琴中,這個過程是相反的(第8行被移到3,第3行被移到第7位)。

http://sqlfiddle.com/#!2/a087b/1

+0

我看到這個後沒有發佈我的答案 - 我有同樣的想法,但爲SIGN函數加上1。如果沒有給定信息的另一個參數,我看不到任何方法來完成給定的任務。 – user1166147