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


139

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

例如,将三个更新更新为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'; 

了一个例子,但是我真的不明白如何进行查询。即:

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

如果在WHERE和IF条件中存在多个条件,我还不太清楚如何执行查询。


这回答了你的问题了吗?MySQL中的多个更新
PeterPan666

Answers:


188

您可以这样操作:

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

1
@ franvergara66。。。我不明白你的评论。 update仅影响已经存在的记录。
Gordon Linoff 2014年

对不起,我的英语先生,当我尝试进行更新mysql时,给我错误:#1062-键“ PRIMARY”的条目“ XXX”重复。当我尝试使用已具有的相同值更新记录时,如果当前值与要更新的记录相同,是否有任何方法可以跳过更新?
franvergara66 2014年

1
@ franvergara66。。。您可能有其他问题。如果cod_user是主键,并且值被重新排序,则多次更新可能是最佳途径。
Gordon Linoff 2014年

1
是的,我知道,真正的问题是有几个助手,然后在尝试进行更新时,主键的完整性受到侵犯。非常感谢您的宝贵时间。
franvergara66 2014年

108

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列表中。如果它们都不是主键(这似乎不太可能),则此方法将始终创建新记录-可能不是想要的。

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


4
谢谢!这是我一直在寻找的最cod_user=VALUES(cod_user), ...
简洁的方法

18
注意:如果表中不存在键,则会添加新行,从而导致不需要的记录。
法拉兹

1
使用永远不会插入的IODKU的技巧,但非常优雅。
Tom Desp

并注意,这种方法要求为表设置主键。
FlameStorm

5
如果您省略了任何不能为null的列,则此方法将不起作用,因为sql仍会在实际求助于更新之前尝试创建新记录。
亚诺·范·奥尔特

15

您可以使用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';

1
您在CASE语句的末尾输入了一个错字:两个逗号彼此相邻。
pmrotule

8
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';

0

要扩展@Trevedhek 答案

如果必须使用非唯一键进行更新,则需要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:删除临时表


0
UPDATE Table1 SET col1= col2 FROM (SELECT col2, col3 FROM Table2) as newTbl WHERE col4= col3

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


-1

我这样做是这样的:

<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进行查询,这将使几个查询
Hristo93
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.