MySQL - 在一个查询中更新具有不同值的多行

Posted

技术标签:

【中文标题】MySQL - 在一个查询中更新具有不同值的多行【英文标题】:MySQL - UPDATE multiple rows with different values in one query 【发布时间】:2014-10-29 17:59:27 【问题描述】:

我试图了解如何使用不同的值更新多行,但我只是不明白。解决方案无处不在,但对我来说似乎很难理解。

例如,1 个查询中的三个更新:

UPDATE table_users
SET cod_user = '622057'
    , date = '12082014'
WHERE user_rol = 'student'
    AND cod_office = '17389551'; 

UPDATE table_users
SET cod_user = '2913659'
    , date = '12082014'
WHERE user_rol = 'assistant'
    AND cod_office = '17389551'; 

UPDATE table_users
SET cod_user = '6160230'
    , date = '12082014'
WHERE user_rol = 'admin'
    AND cod_office = '17389551'; 

我以read 为例,但我真的不明白如何进行查询。即:

UPDATE table_to_update
SET cod_user= IF(cod_office = '17389551','622057','2913659','6160230')
    ,date = IF(cod_office = '17389551','12082014')
WHERE ?? IN (??) ;

如果 WHERE 和 IF 条件中有多个条件,我不完全清楚如何进行查询..有什么想法吗?

【问题讨论】:

这能回答你的问题吗? Multiple Updates in mysql 【参考方案1】:

你可以这样做:

UPDATE table_users
    SET cod_user = (case when user_role = 'student' then '622057'
                         when user_role = 'assistant' then '2913659'
                         when user_role = 'admin' then '6160230'
                    end),
        date = '12082014'
    WHERE user_role in ('student', 'assistant', 'admin') AND
          cod_office = '17389551';

我不明白你的日期格式。日期应使用本地日期和时间类型存储在数据库中。

【讨论】:

如果记录已经存在,我该怎么做才能执行更新 @franvergara66 。 . .我不明白你的评论。 updates 只影响已经存在的记录。 @franvergara66 。 . .你可能有不同的问题。如果cod_user 是主键并且值正在被洗牌,那么多次更新可能是最好的路线。 是的,我明白了,真正的问题是有几个助手,然后在尝试进行更新时,主键的完整性被破坏了。非常感谢您的宝贵时间。 请注意,这会将 user_role 设置为 NULL 对于返回的与三种情况之一不匹配的任何记录。考虑在结尾之前添加一个 ELSE,例如 ELSE cod_user,这样如果字段与 WHEN 子句不匹配,您可以将其设置为自身。【参考方案2】:

您可以使用CASE 语句来处理多个 if/then 场景:

UPDATE table_to_update 
SET  cod_user= CASE WHEN user_rol = 'student' THEN '622057'
                   WHEN user_rol = 'assistant' THEN '2913659'
                   WHEN user_rol = 'admin' THEN '6160230'
               END
    ,date = '12082014'
WHERE user_rol IN ('student','assistant','admin')
  AND cod_office = '17389551';

【讨论】:

您在 CASE 语句的末尾打错字了:两个逗号相邻。【参考方案3】:

MySQL 允许以更易读的方式将多个更新组合到单个查询中。这似乎更适合您描述的场景,更容易阅读,并且避免了那些难以解开的多重条件。

INSERT INTO table_users (cod_user, date, user_rol, cod_office)
VALUES
('622057', '12082014', 'student', '17389551'),
('2913659', '12082014', 'assistant','17389551'),
('6160230', '12082014', 'admin', '17389551')
ON DUPLICATE KEY UPDATE
 cod_user=VALUES(cod_user), date=VALUES(date)

这假定user_rol, cod_office 组合是主键。如果其中只有一个是 主键,则将另一个字段添加到 UPDATE 列表中。 如果它们都不是主键(这似乎不太可能),那么这种方法总是会创建新记录——可能不是我们想要的。

但是,这种方法使准备好的语句更容易构建和更简洁。

【讨论】:

谢谢!这是我一直在寻找的,最干净的方式,我无法弄清楚这个语法,特别是cod_user=VALUES(cod_user), ...,即使来自官方 MySQL 5.6 文档 注意:如果键在表中不存在导致不需要的记录,这将添加新行。 很难使用从不插入的 IODKU,但非常优雅。 并注意这种方法require是为表设置主键的。 如果省略任何不能为空的列,这将不起作用,因为 sql 在实际使用更新之前仍会尝试创建新记录。【参考方案4】:
UPDATE table_name
SET cod_user = 
    CASE 
    WHEN user_rol = 'student' THEN '622057'
    WHEN user_rol = 'assistant' THEN '2913659'
    WHEN user_rol = 'admin' THEN '6160230'
    END, date = '12082014'

WHERE user_rol IN ('student','assistant','admin')
AND cod_office = '17389551';

【讨论】:

【参考方案5】:

扩展@Trevedhek answer,

如果必须使用非唯一键进行更新,则需要 4 次查询

注意:这不是交易安全的

这可以使用临时表来完成。

第 1 步:创建临时表键和要更新的列

CREATE TEMPORARY TABLE  temp_table_users
(
    cod_user varchar(50)
    , date varchar(50)
    , user_rol varchar(50)
    ,  cod_office varchar(50)
) ENGINE=MEMORY

第 2 步:将值插入临时表中

第 3 步:更新原始表

UPDATE table_users t1
JOIN temp_table_users tt1 using(user_rol,cod_office)
SET 
t1.cod_office = tt1.cod_office
t1.date = tt1.date

第 4 步:删除临时表

【讨论】:

【参考方案6】:

我是这样做的:

<update id="updateSettings" parameterType="PushSettings">
    <foreach collection="settings" item="setting">
        UPDATE push_setting SET status = #setting.status
        WHERE type = #setting.type AND user_id = #userId;
    </foreach>
</update>

PushSettings 在哪里

public class PushSettings 

    private List<PushSetting> settings;
    private String userId;

效果很好

【讨论】:

作者想要 1 个查询,很明显他可以用 foreach 来完成,这将进行多个查询【参考方案7】:
UPDATE Table1 SET col1= col2 FROM (SELECT col2, col3 FROM Table2) as newTbl WHERE col4= col3

这里 col4 和 col1 在表 1 中。 col2 & col3 在 Table2 我正在尝试更新每个 col1 其中 col4 = col3 每行的不同值

【讨论】:

【参考方案8】:

php中,你使用mysqli实例的multi_query方法。

$sql = "SELECT COUNT(*) AS _num FROM test;
        INSERT INTO test(id) VALUES (1); 
        SELECT COUNT(*) AS _num FROM test; ";

$mysqli->multi_query($sql);

将结果与更新 30,000 raw 中的事务、插入、案例方法进行比较。

交易:5.5194580554962 插入:0.20669293403625 案例:16.474853992462 多:0.0412278175354

如您所见,多语句查询比最高答案更有效。

以防万一您收到这样的错误消息:

PHP Warning:  Error while sending SET_OPTION packet

你可能需要在mysql配置文件中增加max_allowed_packet

【讨论】:

以上是关于MySQL - 在一个查询中更新具有不同值的多行的主要内容,如果未能解决你的问题,请参考以下文章

SQL:如果存在则更新,否则插入...但对于具有不同值的多行

在具有不同值的多行上更新同一列

更新和交叉查询具有非不同值的表?

更新具有多行的模型

MySQL查找具有相同customerid且具有两个不同值的记录

SQL 查询以查找具有相同列值的多行