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

fra*_*a66 118 mysql sql sql-update

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

例如,三个更新为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'; 
Run Code Online (Sandbox Code Playgroud)

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

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

如果在WHERE和IF条件中存在多个条件,我不完全清楚如何进行查询.任何想法?

Gor*_*off 162

你可以这样做:

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';
Run Code Online (Sandbox Code Playgroud)

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

  • @franvergara66。。。我不明白你的评论。“更新”仅影响已经存在的记录。 (2认同)
  • 请注意,对于返回的任何与三种情况之一不匹配的记录,这会将 user_role 设置为“NULL”。考虑在末尾添加一个 ELSE,如“ELSE cod_user”,以便在与 WHEN 子句不匹配时将该字段设置为其自身。 (2认同)

Tre*_*hek 88

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)
Run Code Online (Sandbox Code Playgroud)

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

但是,这种方法使预编译语句更容易构建,更简洁.

  • 注意:如果表中不存在密钥,则会添加新行,从而导致不需要的记录. (16认同)
  • 谢谢!这是我长时间搜索的,最干净的方式,我无法弄清楚这种语法,特别是`cod_user = VALUES(cod_user),...`,甚至来自官方的MySQL 5.6文档 (4认同)
  • 如果您省略了任何不能为null的列,则此方法将不起作用,因为sql仍会在实际求助于更新之前尝试创建新记录。 (4认同)
  • 使用从不插入的 IODKU 很棘手,但非常优雅。 (3认同)
  • 并注意这种方法 **require** 为表设置了主键。 (3认同)
  • ‘user_rol, cod_office’ 对不一定是主键,它们可以属于 UNIQUE 索引。 (2认同)

Har*_* CO 12

您可以使用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';
Run Code Online (Sandbox Code Playgroud)

  • 您在 CASE 语句末尾犯了一个拼写错误:彼此相邻有 2 个逗号。 (2认同)

小智 7

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';
Run Code Online (Sandbox Code Playgroud)


Sab*_*Sab 7

为了扩展@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
Run Code Online (Sandbox Code Playgroud)

步骤 2:将值插入临时表

第三步:更新原表

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
Run Code Online (Sandbox Code Playgroud)

步骤 4:删除临时表