Mysql重新排序菜单

时间:2012-03-07 00:20:42

标签: php mysql

如果我有三个菜单

id | name | order
--------------------
1  | Foo  | 1
2  | Bar  | 2
3  | Blah | 3

并点击链接menu/up/1,我需要设置标识为12的菜单和标识为21的菜单。< / p>

我试过(PDO)

public static function goDown($id) {
    if(!$id) {
        return false;
    }

    self::connect();
    self::prepare('SELECT count(*) FROM menu');
    $count = self::fetch();

    if(isset($count['count(*)'])) {
        self::prepare('UPDATE menu SET order = order - 1 WHERE order = :count');
        self::bindValue('count', $count['count(*)']);
        self::execute();

        self::prepare('UPDATE menu SET order = order + 1 WHERE id = :id AND order < :count');
        self::bindValue('id', $id);
        self::bindValue('count', $count['count(*)']);

        return self::execute();
    }
}

谢谢!

编辑 - 我的解决方案:

public static function goDown($id) {
    if(!$id) {
        return false;
    }

    self::connect();
    self::prepare('SELECT count(*) FROM menu');
    $count = self::fetch();

    if(isset($count['count(*)'])) {
        self::prepare('SELECT ordem FROM menu WHERE id = :id LIMIT 1');
        self::bindValue('id', $id);
        $ordem = self::fetch();

        self::prepare('UPDATE menu SET ordem = ordem - 1 WHERE ordem = :ordem');
        self::bindValue('ordem', $ordem['ordem'] + 1);
        self::execute();

        self::prepare('UPDATE menu SET ordem = ordem + 1 WHERE id = :id AND ordem < :count');
        self::bindValue('id', $id);
        self::bindValue('count', $count['count(*)']);

        return self::execute();
    }
}

2 个答案:

答案 0 :(得分:1)

我不知道你的表定义和键是如何设置的,但你可能需要一段重叠的数字。如果可以,那就做这样的事情:

最安全的:

SELECT order FROM menu WHERE id = :id; /* One to go up; */
SELECT id, order FROM menu WHERE order = :existingOrder + 1; /* One to go down */

UPDATE menu SET order = order + 1 WHERE id = :id; /* Putting it up */
UPDATE menu SET order = :existingOrder WHERE id = :existingId

这使用额外的查询,但更安全。您也可以验证它不在顶部/底部,因为这会导致问题。

答案 1 :(得分:0)

检查this

将它转换为PDO很容易:

set @id := 10;
select @count := count(*) from t;
select @prevOrder := least(anorder + 1, @count) from t where id = @id;
select @prevId := id from t where anorder = @prevOrder;

update t set anorder = anorder - 1 where id = @prevId;    
update t set anorder = anorder + 1 where id = @id;

基本上它会降低所选ID(@id)的顺序而不会下降(这是least函数)并增加之前在那个地方的ID。