让我们假设你有两个逗号分隔的列表你的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;
说明
内一系列工会建立从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, ',', '')))
因为我们已经得到了分离器的一个occurence少,我们加1的区别带有分隔符的列表的长度和没有出现分隔符的所有列表的长度。
然后我们使用JOIN操作对外部UPDATE语句中的id值执行UPDATE。
看来它的工作this fiddle。
相信我:这比痛苦的逐行更新要快得多。
但我一次只有10.000个ID和值。我可以像使用这么多值一样使用sql变量吗? – Jim 2014-09-04 07:01:10
您可以达到[最大允许数据包](http://dev.mysql.com/doc/refman/5.5/en/packet-too-large.html)限制。这主要取决于你的价值观的大小。如果值是例如字符串,那么列表的分隔符也可能不包含在这些列表中。如果你接近这个限制,你可以分批处理1000个。所以你会大大限制查询的数量。 – VMai 2014-09-04 07:07:01
+ 1.我需要仔细研究这个答案,以充分理解它。一个问题。这比使用'CASE id WHEN 1 then val1 etc'更高效,并且通过字符串concats在应用程序中构造这个查询? – Jim 2014-09-04 07:23:53