按自定义顺序运行UPDATE查询

时间:2017-11-24 21:51:15

标签: mysql sql-update increment

有没有办法通过特定的自定义订单更新表中的所有记录?我特别指的是一种情况,当实际的订单来自“外部”时。 (例如,作为POST值)。

例如,有一个表

   id | title | order_idx
   ----------------------
    1 | lorem | 1
    2 | ipsum | 2
    3 | dolor | 3

我有一个提交隐藏字段的表单,按以下顺序携带ID值:2,3,1 我想更新表,以便在每个下一行中向order_idx添加增量编号,按表单字段提供的ID顺序。所以在这种情况下,最终结果应如下所示:

   id | title | order_idx
   ----------------------
    1 | lorem | 3
    2 | ipsum | 1
    3 | dolor | 2

这可以在单个UPDATE查询中以某种方式完成,而不是在php循环中运行3个查询(每个包含WHERE子句)

2 个答案:

答案 0 :(得分:0)

您可以在赋值语句中使用条件表达式,如下所示:

UPDATE t 
SET x = CASE 
WHEN 2 THEN 1 
WHEN 3 THEN 2 
WHEN 1 THEN 3
ELSE x
WHERE ....

参数:

UPDATE t 
SET x = CASE 
WHEN ? THEN 1 
WHEN ? THEN 2 
WHEN ? THEN 3
ELSE x
WHERE ....

在任何一种情况下,查询很可能需要动态构建,以便考虑不同数量的商品。

由于您的评论可能表示数百...... MySQL的查询长度限制为(reference)

对于大量的人,我会开始推荐一种不同的方法。

Step 1) CREATE TEMPORARY TABLE `newOrder` (id INT, new_order_idx INT);
Step 2) INSERT id's and their new order into the temp table.
Step 3) UPDATE t INNER JOIN newOrder AS n ON t.id = n.id SET t.order_idx = n.new_order_idx WHERE ...
Step 4) DROP TEMPORARY TABLE newOrder;

流程本身不再是单个查询;但UPDATE是。

注意:如果您有一个涉及order_idx的唯一密钥,我完全相信其中任何一个都可行。在我需要保持唯一性的情况下,通常的解决方案是将记录在一步中调整到完全不同的范围,然后在第二步中调整到新的位置。 (像UPDATE t SET order_idx = -1 * order_idx WHERE ...这样的东西可以作为本答案第二部分中的前3步范围转换。)

答案 1 :(得分:0)

使用 ON DUPLICATE KEY UPDATE ,如下所示:

INSERT INTO table (id, order_idx) VALUES (1,3),(2,1),(3,2)
ON DUPLICATE KEY UPDATE order_idx=VALUES(order_idx);

因此,您可以为每一行动态设置 order_idx

INSERT INTO table (id, order_idx) 
VALUES (1,order_list[0]),(2,order_list[1]),(3,order_list[2])
ON DUPLICATE KEY UPDATE order_idx=VALUES(order_idx);