讓我們假設你有兩個逗號分隔的列表你的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