$consulta = "UPDATE `list`
SET `pos` = $pos
WHERE `id_item` IN (SELECT id_item
FROM lists
WHERE pos = '$item'
ORDER BY pos DESC
LIMIT 1)
AND id_usuario = '$us'
AND id_list = '$id_pl'";
问题是,这个查询在foreach中,它想要更新列表中项目的顺序。在我这样之前:
$consulta = "UPDATE `list`
SET `pos` = $pos
WHERE `$pos` = '$item'
AND id_usuario = '$us'
AND id_list = '$id_pl'";
但是当我更新pos 2 - > 1,然后1 - > 2,结果是2次2而没有1 ...
此查询是否有解决方案?
答案 0 :(得分:1)
重新编号列表中的项目非常棘手。当您使用多个单独的SQL语句重新编号列表中的项目时,它甚至更加棘手。
您的内部子选择语句也未正确约束。您需要一个额外的条件,例如:
AND id_list = '$id_pl'
可能有很多方法可以做到这一点,但可能最简单的方法如下。我假设:
foreach
循环以所需的顺序生成$pos
值(1,2,...)$id_pl
的值对于循环foreach
循环为每次迭代提供$us
和$item
的值$id_pl
,$us
和$item
的组合唯一标识list
表格中的行pos
个值
建议的解决方案有两个阶段:
这种技术避免了关于是否已经调整了位置的行被同一查询重新读取的任何复杂问题。
循环内部:
foreach ...
...$pos, $item, $us...
UPDATE list
SET pos = $pos + 100
WHERE id_item = '$item'
AND id_usuario = '$us'
AND id_list = '$id_pl'
AND pos < 100
end foreach
UPDATE list
SET pos = pos - 100
WHERE id__list = '$id_pl';
如果您不知道列表的大小,可以在循环中指定负pos值,并在循环后转换为正值,或者转换为许多其他等效映射中的任何一个。关键是要更新表,以便循环中的新pos号与旧数字不相交,然后在循环后调整新值。
替代技术创建一个临时表,将旧数字映射到new,然后执行单个UPDATE语句,该语句将旧pos值更改为单个操作中所有行的new值。这可能更有效,特别是如果映射表可以作为查询生成,但这取决于重新编号是否是算法。所示的技术虽然有点笨拙,但可以用于任意重新编号。