Mysql 更新/转换字段值的最佳方法

Mysql 更新/转换字段值的最佳方法,mysql,sql,Mysql,Sql,因此,我需要更新/转换mysql表中名为status\u id的字段,基本上如下所示: WHERE | SHOULD BE 0 | 0 1 | 1 2 | 4 3 | 8 4 | 9 5 | 10 6 | 6 7 | 2 8 | 11 我想了几种方法,但我不确定哪一种是最好的 第一个: 使用一些过渡元素,在这种情况下,所需的最终值为+100 更新myTable 设置状态\u

因此,我需要更新/转换mysql表中名为
status\u id
的字段,基本上如下所示:

WHERE | SHOULD BE
  0   |    0
  1   |    1
  2   |    4
  3   |    8
  4   |    9
  5   |   10
  6   |    6
  7   |    2
  8   |   11
我想了几种方法,但我不确定哪一种是最好的

第一个:

使用一些过渡元素,在这种情况下,所需的最终值为+100

更新myTable
设置状态\u id=100
其中status_id=0;
-- ...
更新myTable
设置状态\u id=111
其中status_id=8;
-- ...
更新myTable
设置状态\u id=0
其中状态_id=100;
-- ...
更新myTable
设置状态\u id=11
其中status_id=111;
第二条:

使用
CASE

UPDATE myTable SET status_id = 
CASE 
    WHEN status_id = 0 THEN 0
    -- ...
    WHEN status_id = 8 THEN 11
    ELSE status_id
END

这只会做一次,我只是想确保我不会把事情搞砸(我有备份,但不需要它们总是好的)

您可以将您的值放在“持有者表”中

(等等,等等,我给出了示例值,输入您自己的真实值。)

这意味着您拥有不含糊的“匹配”

以上是一种“基于集合”的方法

如果必须按顺序进行(也就是说,在第一次更新完成之前,不能进行第二次更新),则必须逐个(也称为逐行)更新RBAR

参考:


如果您想获得更多乐趣,可以使用MySQL的JSON功能:

UPDATE myTable SET status_id = JSON_EXTRACT(
    CAST('
        {
            "0": 0,
            "1": 1,
            "2": 4,
            "3": 8,
            "4": 9,
            "5": 10,
            "6": 6,
            "7": 2,
            "8": 11
        }'
        AS JSON
    ),
    CONCAT('$."', status_id, '"')
)

实际上,它可以更方便地编写和维护(在某些情况下,还可以更干净、更简单地在代码中自动构造)。

对于MySql 8.0+,您可以创建一个CTE,返回每对当前和新的
状态id
,并将其连接到
UPDATE
语句中的表中:

WITH cte(status_id, new_status_id) AS (VALUES
  ROW(0, 0),
  ROW(1, 1),
  ROW(2, 4),
  ROW(3, 8),
  ROW(4, 9),
  ROW(5, 10),
  ROW(6, 6),
  ROW(7, 2),
  ROW(8, 11)
)
UPDATE myTable t
INNER JOIN cte c ON c.status_id = t.status_id
SET t.status_id = c.new_status_id
请参阅。

对于早期版本,请将子查询连接到表:

UPDATE myTable t
INNER JOIN (
  SELECT 0 status_id, 0 new_status_id UNION ALL
  SELECT 1, 1 UNION ALL
  SELECT 2, 4 UNION ALL
  SELECT 3, 8 UNION ALL
  SELECT 4, 9 UNION ALL
  SELECT 5, 10 UNION ALL
  SELECT 6, 6 UNION ALL
  SELECT 7, 2 UNION ALL
  SELECT 8, 11
) c ON c.status_id = t.status_id
SET t.status_id = c.new_status_id
请参阅。

请注意,我看不出有任何理由保留两个值相等的位置,但MySql在这种情况下不会执行更新。

UPDATE myTable
SET status_id = FIND_IN_SET(status_id, '1,7,x,2,x,6,x,3,4,5,8')
WHERE status_id BETWEEN 0 AND 8;


注:这是一种特殊情况,允许使用这种特殊解决方案。

我个人会使用
情况
语句在一次
更新中显式地更改它们。您可以检查并再次检查状态更改,并将其作为单个事务运行。首先备份表或数据库,以防万一。
case
是正确的选择。mySql上没有
decode函数。我们中的几个人都在使用相同的概念。(将所有行放在“holder”中,然后执行更新)。向上投票。我们几个人都在围绕着同一个概念。(将所有行放在“holder”中,然后执行更新)。向上投票。但这绝对是“额外的乐趣”:
UPDATE myTable t
INNER JOIN (
  SELECT 0 status_id, 0 new_status_id UNION ALL
  SELECT 1, 1 UNION ALL
  SELECT 2, 4 UNION ALL
  SELECT 3, 8 UNION ALL
  SELECT 4, 9 UNION ALL
  SELECT 5, 10 UNION ALL
  SELECT 6, 6 UNION ALL
  SELECT 7, 2 UNION ALL
  SELECT 8, 11
) c ON c.status_id = t.status_id
SET t.status_id = c.new_status_id
UPDATE myTable
SET status_id = FIND_IN_SET(status_id, '1,7,x,2,x,6,x,3,4,5,8')
WHERE status_id BETWEEN 0 AND 8;