mysql - 如何使用一组记录的值列表中的值更新列

标签 mysql sql sql-update

我逐行更新表格:

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/

相关文章:

PHP 多个数据库连接失败

java - 使用PreparedStatements - 使用多个参数(未知数量)进行更新

php - 如何仅删除选定的帖子?

java - 使用 Hibernate 时如何打印带有参数值的查询字符串

mysql - 每天的 SQL 计数

php - 插入新记录后更新列

php - 托管如何与 PHP/MySQL 一起使用?

php - 在 PHP 中,使用 "LIKE"从 MySQL 搜索结果中获取整个单词

mysql - 是否可以将相同的 UPDATE 逻辑应用于 MySQL 中单个语句中的多个列?

mysql - 如何在SQL语句中连接两个字符串?