查询:
$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的两倍且没有1 ...
这个查询有解决方案吗?
最佳答案
对列表中的项目重新编号非常棘手。当您使用多个单独的SQL语句对列表中的项目重新编号时,这将更加棘手。
您的内部sub-select语句也没有受到适当的约束。您需要额外的条件,例如:
AND id_list = '$id_pl'
可能有很多方法可以做到这一点,但是下面可能是最简单的一种方法。我假设:
未显示的
foreach
循环按所需顺序(1、2,...)生成$pos
值$id_pl
的值在循环中是恒定的foreach
循环为每次迭代提供$us
和$item
的值$id_pl
,$us
和$item
的组合唯一标识list
表中的行最多可以担心100个
pos
值您可以在语句序列周围使用显式事务
建议的解决方案包括两个阶段:
为每行分配100 +位置,以将其放置在新位置
从每个位置减去100
此技术避免了有关是否已由同一查询重新读取已调整位置的行的任何复杂问题。
循环内:
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,或者使用许多其他等效映射中的任何一个。关键是更新表,以使循环中的新pos号与旧数字脱节,然后在循环后调整新值。
替代技术创建一个临时表,该表将旧数字映射到新数字,然后执行单个UPDATE语句,从而在一次操作中将所有行的旧pos值更改为新的pos值。这可能会更有效,尤其是如果可以将映射表作为查询生成时,但这取决于重新编号是否是算法上的。所显示的技术虽然有些笨拙,但可以使其适用于任意重编号。
关于mysql - 使用SQL查询重新编号列表中的项目?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5366605/