您如何识别表格中的“第一行”? “第二行”怎么样?
要使用 UPDATE 语句,我首先要使用 SELECT 语句,该语句返回行以及要分配的新值。
您当前拥有的“数组”,如果将其转换为表格将是最简单的。如果您不想定义表并加载它,我们可以使用内联视图,但语句的大小可能会受到限制。
如果我们运行这个查询,例如:
SELECT 1 AS rownum, 'code-1' AS code
UNION ALL SELECT 2, 'code-2'
UNION ALL SELECT 3, 'code-3'
我们返回结果集中的三行,我们可以像表格一样引用它们。使用额外的 UNION ALL SELECT 扩展它以添加额外的行。
为了从我们要更新的表中获取对应的rownum值,我们返回主键(或唯一的非空键),并按照我们想要的顺序返回,所以第一行的rownum为1,第二行的 rownum 为 2,以此类推。例如:
SELECT r.id
, @rn := @rn + 1 AS rowumn
FROM mytable r
CROSS JOIN ( SELECT @rn := 0 ) i
ORDER BY r.name, r.id
有了这两个结果,我们可以连接回我们要更新的表,返回我们要分配给行的新代码值,例如:
SELECT t.id
, t.name
, t.code AS old_code
, c.code AS new_code
, o.rownum
FROM ( SELECT 1 AS rownum, 'code-1' AS code
UNION ALL SELECT 2, 'code-2'
UNION ALL SELECT 3, 'code-3'
) c
JOIN ( SELECT r.id
, @rn := @rn + 1 AS rowumn
FROM mytable r
CROSS JOIN ( SELECT @rn := 0 ) i
ORDER BY r.name, r.id
) o
ON o.rownum = c.rownum
JOIN mytable t
ON t.id = o.id
一旦我们对返回我们想要更新的行以及我们想要分配给每一行的新值感到满意,我们可以通过将SELECT ... FROM 替换为UPDATE 将其转换为UPDATE 语句,并且在语句末尾添加SET 子句。 (如果我们有 WHERE 子句,则在 WHERE 子句之前。)
UPDATE ( SELECT 1 AS rownum, 'code-1' AS code
UNION ALL SELECT 2, 'code-2'
UNION ALL SELECT 3, 'code-3'
) c
JOIN ( SELECT r.id
, @rn := @rn + 1 AS rowumn
FROM mytable r
CROSS JOIN ( SELECT @rn := 0 ) i
ORDER BY r.name, r.id
) o
ON o.rownum = c.rownum
JOIN mytable t
ON t.id = o.id
SET t.code = c.code
我就是这样做的。
如果“新代码”数组中的行数很大,我会创建一个表,并将数组值加载到表中。然后将内联视图查询c 替换为对表的引用。
FROM my_new_code_table c
或者,我可以将语句分成可管理的块。做 20 个代码,然后为下一组 20 行:
( SELECT 21 AS rownum, 'code-21' AS code
UNION ALL SELECT 22, 'code-22'
...
UNION ALL SELECT 40, 'code-40'
) c