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 。 . .我不明白你的评论。update
s 只影响已经存在的记录。
@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:如果存在则更新,否则插入...但对于具有不同值的多行