php - SQL主键重新排序的简明方法

标签 php mysql sql

解决了我的解决方案在底部

<小时/>

我正在开发一个围绕使用 SQL 表的主键对事物进行排序而构建的系统。我正在尝试在 UI 中添加重新排序的功能。

理想情况下,我想要一个简洁高效的通用解决方案,不需要复制整个表。如果可能的话,我还希望解决方案不需要重写整个系统来使用不同的 key /ID。

我想出的最好的(在我看来)解决方案似乎不起作用,我不太明白为什么。

$old_ids = $_POST["oldid"];
$new_ids = $_POST["newid"];
$i = 0;
foreach ($old_ids as $oid) {
    $nid = $new_ids[$i];
    $db->insert("UPDATE links SET sort = $oid WHERE id = $oid");
    $db->insert("UPDATE links SET id = -$nid WHERE sort = $oid");
    $i++;
}
$i = 0;
foreach ($old_ids as $oid) {
    $nid = $new_ids[$i];
    $db->insert("UPDATE links SET id = $nid WHERE id = -$oid");
    $i++;
}
$db->insert("UPDATE links SET sort = NULL");

将顶行(第 1 行)移动到底部(第 6 行)时 PHP 输出 SQL

UPDATE links SET sort = 2 WHERE id = 2;
UPDATE links SET id = -1 WHERE sort = 2;
UPDATE links SET sort = 3 WHERE id = 3;
UPDATE links SET id = -2 WHERE sort = 3;
UPDATE links SET sort = 4 WHERE id = 4;
UPDATE links SET id = -3 WHERE sort = 4;
UPDATE links SET sort = 5 WHERE id = 5;
UPDATE links SET id = -4 WHERE sort = 5;
UPDATE links SET sort = 6 WHERE id = 6;
UPDATE links SET id = -5 WHERE sort = 6;
UPDATE links SET sort = 1 WHERE id = 1;
UPDATE links SET id = -6 WHERE sort = 1;
UPDATE links SET id = 1 WHERE id = -2;
UPDATE links SET id = 2 WHERE id = -3;
UPDATE links SET id = 3 WHERE id = -4;
UPDATE links SET id = 4 WHERE id = -5;
UPDATE links SET id = 5 WHERE id = -6;
UPDATE links SET id = 6 WHERE id = -1

当我在 phpmyadmin 中运行它时,所有 ID 都重置为默认的 1-6(正)值,我收到以下错误

UPDATE links SET id = -5 WHERE sort = 6;
#1062 - Duplicate entry '-5' for key 'PRIMARY'

我还没有看到任何似乎能够以有效或简洁的方式解决 key 重复问题的方法。如果没有特别简洁或有效的方法来解决这个问题,那么最有效的方法是什么?

我觉得我忽略了一些显而易见的事情,但我还没有找到解决方案。任何有关如何完成我需要的帮助或见解将不胜感激。我已经为此绞尽脑汁好几个小时了。

解决方案

这就是我想出的办法,似乎可以实现我想要的。

$old_ids = $_POST["oldid"];
$new_ids = $_POST["newid"];
$i = 0;
$db->insert("ALTER TABLE links CHANGE id id INT(255) NOT NULL");
foreach ($old_ids as $oid) {
    $nid = $new_ids[$i];
    $db->insert("UPDATE links SET id = -$nid WHERE id = $oid");
    $i++;
}
foreach ($old_ids as $oid) {
    $db->insert("UPDATE links SET id = $oid WHERE id = -$oid");
}
$db->insert("ALTER TABLE links CHANGE id id INT(255) NOT NULL AUTO_INCREMENT");

诀窍是临时切换 id 列上的 AUTO_INCRMENT。除此之外,我意识到根本不需要专用的排序列。

显然这需要一些错误处理,但我希望切换AUTO_INCRMENT的总体思路,将新的id值设置为负数,迭代将它们反转为正数将帮助面临同样问题的人。

最佳答案

这就是我想出的办法,似乎可以实现我想要的。

$old_ids = $_POST["oldid"];
$new_ids = $_POST["newid"];
$i = 0;
$db->insert("ALTER TABLE links CHANGE id id INT(255) NOT NULL");
foreach ($old_ids as $oid) {
    $nid = $new_ids[$i];
    $db->insert("UPDATE links SET id = -$nid WHERE id = $oid");
    $i++;
}
foreach ($old_ids as $oid) {
    $db->insert("UPDATE links SET id = $oid WHERE id = -$oid");
}
$db->insert("ALTER TABLE links CHANGE id id INT(255) NOT NULL AUTO_INCREMENT");

诀窍是临时切换 id 列上的 AUTO_INCRMENT。除此之外,我意识到根本不需要专用的排序列。

显然这需要一些错误处理,但我希望切换AUTO_INCRMENT的总体思路,将新的id值设置为负数,迭代将它们反转为正数将帮助面临同样问题的人。

关于php - SQL主键重新排序的简明方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30496463/

相关文章:

java - 基于列标签的 CachedRowSetImpl getString 抛出 "Invalid column name"

MySQL db 消失了如何跟踪发生了什么?

mysql - 如何自动增加mysql中特定列的值

mysql - MySQL中的递归组结构

mysql - 如何从mysql过程中的表中获取新列?

mysql - Zend 框架 - mysql 查询

php - 根据用户上次查看获取每个主题的新帖子数

php - 如何使用 GET 方法将 GET 参数传递给 Laravel?

php - MySQLi 不返回错误代码

php - facebook php sdk - 如果用户未授予权限(身份验证失败)则捕获