2

我有一个应用程序,用户可以创建不同的容器,这些容器都可以使用 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 查询,以便它根据一个移动更新所有用户容器位置。?

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

现在我正在使用 PHP 中的循环来执行此操作,但我希望在 MYSQL 中找到更有效的方法来执行此操作

谢谢您的帮助。

4

2 回答 2

3

此操作可以在单个 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 演示在这里: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
于 2013-07-27T22:57:56.753 回答
2

您可以通过 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
    
于 2013-07-27T22:20:59.623 回答