我有一个应用程序,用户可以创建不同的容器,这些容器都可以使用与此页面类似的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中找到一种更有效的方法
感谢您的帮助。
答案 0 :(得分:1)
您可以使用3个查询来实现此目的:
在新位置之后和移动项目的旧位置之前增加项目的位置:
UPDATE container_position SET container_position = container_position + 1 WHERE container_position >= $new_position AND container_position < $old_position
在移动项目的旧位置之后减少项目的位置:
UPDATE container_position SET container_position = container_position - 1 WHERE container_position > $old_position
设置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