MYSQL查询,用于根据对象的位置变化更新多行

时间:2013-07-27 22:03:05

标签: mysql

我有一个应用程序,用户可以创建不同的容器,这些容器都可以使用与此页面类似的JqueryUI-lib进行排序:http://jqueryui.com/sortable/#placeholder

在进行可排序的拖放操作后,我会根据容器的新位置执行Ajax调用以更新我的数据库,这样我可以在下次返回时向用户显示相同的顺序(或者如果他们刷新页面)

我的container_position表如下所示:

| ID   |    UserID   | Container_name | Container_position|
|:-----|------------:|:--------------:|:-----------------:|
| 1    |      23     |  ItemA         |        0          |
| 2    |      23     |  ItemB         |        1          |
| 3    |      23     |  ItemC         |        2          |
| 4    |      23     |  ItemD         |        3          |
| 5    |      23     |  ItemE         |        4          |

问题是如何编写MYSQL查询,以便根据一个移动更新所有Users容器位置。?

假设用户将itemE移动到第二个位置(位置1)这应该使ItemA的位置= 0(未更改),ItemB = 3,ItemC = 4,ItemD = 5

现在我用PHP中的循环做这个,但我希望在MYSQL中找到一种更有效的方法

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用3个查询来实现此目的:

  1. 在新位置之后和移动项目的旧位置之前增加项目的位置:

    UPDATE container_position SET container_position = container_position + 1 WHERE container_position >= $new_position AND container_position < $old_position
    
  2. 在移动项目的旧位置之后减少项目的位置:

    UPDATE container_position SET container_position = container_position - 1 WHERE container_position > $old_position
    
  3. 设置current_item的新位置:

    UPDATE container_position SET container_position = $new_position WHERE ID = $moved_item_id
    

答案 1 :(得分:1)

此操作可以在单个SQL语句中完成。

要移动列表中的单个元素“向上”(较低的值Container_position),例如将位置4中的项目移动到位置1,您可以使用此表达式为列导出新值:

IF(cp >= 1 AND cp < 4, cp+1, IF(cp = 4 ,1 ,cp))

要向下移动单个元素(Container_position的值更高),例如将位置3中的项目移动到位置5,您可以使用以下表达式:

IF(cp <= 5 AND cp > 3, cp-1, IF(cp = 3, 5, cp))

为了使表达式更具可读性,我将column_name缩写为cp

如果您想使用绑定变量将其推广到预准备语句中 (:np是新位置的值,:op是旧位置的值),只需做一个简单的测试即可确定它是“向上”还是“向下”:

UPDATE container_position_table t
SET t.cp = IF(:np < :op,
           IF(t.cp >= :np AND t.cp < :op, t.cp+1, IF(t.cp = :op, :np, t.cp)),
           IF(t.cp <= :np AND t.cp > :op, t.cp-1, IF(t.cp = :op, :np, t.cp)))
WHERE t.cp BETWEEN LEAST(:np,:op) AND GREATEST(:np,:op)

(显然,您需要将cp替换为列的实际名称。)

SQL Fiddle demonstation here: http://sqlfiddle.com/#!2/b4a80/1


第一个表达式是等效的SQL-92兼容表达式的MySQL简写:

CASE WHEN cp >= 1 AND cp < 4 THEN cp+1
 ELSE CASE WHEN cp = 4 THEN 1 ELSE cp END
END