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

我试图了解如何更新具有不同值的多行,我只是没有得到它。解决方案无处不在,但对我来说,它看起来很难理解。

例如,对一个查询进行三次更新:

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 (??) ;

我不完全清楚如何做查询,如果有多个条件在哪里和在if条件..有什么想法?

437378 次浏览

你可以这样做:

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

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

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

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列表中。 如果它们都不是主键(这似乎不太可能),那么这种方法总是会创建新记录——这可能不是我们想要的

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

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

扩展@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:删除临时表

我是这样做的:

<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;
}

它运行正常

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

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

在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中的事务、插入、case方法的结果。

< p > < >强事务:5.5194580554962 < br > 插入:0.20669293403625 < br > 例:16.474853992462 < br > 多:0.0412278175354 < br > < /强> < / p >

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

以防万一你得到这样的错误信息:

PHP Warning:  Error while sending SET_OPTION packet

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