【问题标题】:Update order column from a list of IDS从 IDS 列表更新订单列
【发布时间】:2019-01-15 04:16:26
【问题描述】:

我在 MySQL 服务器 5.7.24 上有一个 N 个 ID 的列表(例如:803、518、361)

当前值为

+-----+-------+
| id  | order |
+-----+-------+
| 361 |     1 |
| 518 |     2 |
| 803 |     3 |
+-----+-------+

我想从 id 列表中更新 order 列,从 id 位置获取订单。

此查询为每个id 返回正确的rownum

SELECT `id`, (@rownumber := @rownumber + 1) `rownum`
FROM `comments`
CROSS JOIN (SELECT @rownumber := 0) `cross`
WHERE `id` IN (803, 518, 361)
ORDER BY FIELD (`id`, 803, 518, 361) ASC;

+-----+--------+
| id  | rownum |
+-----+--------+
| 803 |      1 |
| 518 |      2 |
| 361 |      3 |
+-----+--------+

但在更新时,此位置未设置:

UPDATE `comments` `target`
JOIN (
    SELECT `id`, (@rownumber := @rownumber + 1) `rownum`
    FROM `comments`
    CROSS JOIN (SELECT @rownumber := 0) `cross`
    WHERE `id` IN (803, 518, 361)
    ORDER BY FIELD (`id`, 803, 518, 361) ASC
) `source` ON `target`.`id` = `source`.`id`
SET `target`.`order` = `source`.`rownum`;

Query OK, 0 rows affected (0.00 sec)
Rows matched: 3  Changed: 0  Warnings: 0

订单值未更新:

SELECT `id`, `order` FROM `comments`
WHERE `id` IN (361, 518, 803)
ORDER BY `order` ASC;

+-----+-------+
| id  | order |
+-----+-------+
| 361 |     1 |
| 518 |     2 |
| 803 |     3 |
+-----+-------+
3 rows in set (0.01 sec)

查询的问题在哪里?

谢谢!

更新 1:

同样,不工作

UPDATE `comments` `target`, (
    SELECT `id`, (@rownumber := @rownumber + 1) `rownum`
    FROM `comments`
    CROSS JOIN (SELECT @rownumber := 0) `cross`
    WHERE `id` IN (803, 518, 361)
    ORDER BY FIELD (`id`, 803, 518, 361) ASC
) `source`
SET `target`.`order` = `source`.`rownum`
WHERE `target`.`id` = `source`.`id`;

【问题讨论】:

  • 我无法重现您的错误,它对我有用。
  • @P.Salmon 哦,这很奇怪...我有一个脚本,在 SQL 上具有固定的 ID,要连续执行进行测试,但无法正常工作。
  • FIELD (id, 803, 518, 361) 在第一个查询中与 FIELD (803, 518, 361) 在第二个查询中 - 这是您发布的副本中的错误还是您实际使用的代码中的不同?
  • @sticky 位很好,
  • @stickybit 是复制和粘贴错误。在我的代码中,我使用的是FIELD (id, 803, 518, 361)

标签: mysql


【解决方案1】:

由于id 是主键,您可以这样做:

UPDATE `comments`
       SET `order` = field(`id`,
                           803,
                           518,
                           316)
       WHERE `id` IN (803,
                      518,
                      361);

field() 已经生成了123

【讨论】:

    【解决方案2】:

    以下查询应该可以解决问题:

    SET @rownumber = 0;
    UPDATE comments
    SET `order` = @rownumber:= @rownumber + 1
    WHERE id IN (803, 518, 361)
    ORDER BY id DESC;
    

    this db fiddle

    【讨论】:

    • 我不能这样做,因为它来自 PHP 脚本,我一次只能执行一个查询。不允许多次查询。
    • mysqli::multi_query 是你的朋友@Lito
    • 我正在使用 PDO ;)
    • @Lito : 好的,那么你可以简单地运行这两个语句,一个接一个
    【解决方案3】:

    由于我正在处理 PHP 上的查询,感谢@GMB 关于运行两个不同语句的想法:

    $db->exec('SET @rownumber = 0;');
    
    $db->exec('
        UPDATE `comments`
        SET `order` = @rownumber := @rownumber + 1
        WHERE `id` IN (803, 518, 361)
        ORDER BY FIELD (`id`, 803, 518, 361) ASC;
    ');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 2013-04-09
      • 2021-12-08
      相关资源
      最近更新 更多