我逐行更新表格:
UPDATE table
SET col = $value
WHERE id = $id
现在,如果我更新,例如10000 条记录,每条记录获得 $value
,但哪个 $id
获得哪个 $value
并不重要。我唯一的要求是我更新的所有记录都以 $value
结束。
那么我如何才能将此更新转换为类似
UPDATE table
SET col ?????? what here from a $value_list???
WHERE id IN ($id_list)
即传递列表 ID 并以某种方式获取值和 ID 范围一个值
最佳答案
假设您有两个以逗号分隔的 ID 和值列表,其中的项目数相同。然后你可以用这样的语句进行更新:
-- the list of the ids
SET @ids = '2,4,5,6';
-- the list of the values
SET @vals = '17, 73,55, 12';
UPDATE yourtable
INNER JOIN (
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(t.ids, ',', n.n), ',', -1) id,
SUBSTRING_INDEX(SUBSTRING_INDEX(t.vals, ',', n.n), ',', -1) val
FROM (SELECT @ids as ids, @vals as vals) t
CROSS JOIN (
-- build for up to 1000 separated values
SELECT
1 + a.N + b.N * 10 + c.N * 100 AS n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c
ORDER BY n
) n
WHERE n <= (1 + LENGTH(t.ids) - LENGTH(REPLACE(t.ids, ',', '')))
) t1
ON
yourtable.id = t1.id
SET
yourtable.val = t1.val;
解释
UNION 的内部系列构建了一个包含 1 到 1000 之间数字的表。您应该能够根据需要扩展此机制:
-- build for up to 1000 separated values
SELECT
a.N + b.N * 10 + c.N * 100 + 1 AS n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c
ORDER BY n
我们使用这个数字通过嵌套的 SUBSTRING_INDEX
调用从我们的列表中取出项目
SUBSTRING_INDEX(SUBSTRING_INDEX(t.ids, ',', n.n), ',', -1) id,
SUBSTRING_INDEX(SUBSTRING_INDEX(t.vals, ',', n.n), ',', -1) val
WHERE 子句获取(只确定两个列表之一)列表中的项数:
WHERE n <= (1 + LENGTH(t.ids) - LENGTH(REPLACE(t.ids, ',', '')))
因为我们少了一次分隔符,所以我们将带分隔符的列表长度与不带分隔符的列表长度之差加 1。
然后我们通过对外部 UPDATE 语句中的 id 值进行 JOIN 操作来执行 UPDATE。
查看它在 this fiddle 中的工作情况.
相信我:这比痛苦的逐行更新要快得多。
关于mysql - 如何使用一组记录的值列表中的值更新列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25652268/