[mysql] mysql 在update中实现子查询的方式

mysql update中实现子查询的方式

 

---测试代码---------------

drop table if exists tb;
create table IF NOT EXISTS tb (Name varchar(10),Time1 datetime,Time2 datetime,Time3 varchar(8),Time4 varchar(8) );
insert tb (name,time1,time2)
select '1','2010-08-04  05:06:26 ','2010-08-04  05:06:29 ' union all
select '1','2010-08-04  05:06:33 ','2010-08-04  09:53:32 ' union all
select '1','2010-08-04  06:06:26 ','2010-08-04  07:06:29 ' union all
select '1','2010-08-05  09:43:10 ','2010-08-05  12:43:50 ' union all
select '1','2010-08-05  05:43:56 ','2010-08-05  07:23:33 ' union all
select '1','2010-08-06  09:43:56 ','2010-08-06  14:55:59 ' union all
select '1','2010-08-07  09:04:56 ','2010-08-07  17:43:56 ' union all
select '1','2010-08-08  08:56:10 ',null;

update tb set time3=timediff(time2,time1);
select * from tb;

update tb a,
(select SEC_TO_TIME(sum(TIME_TO_SEC(time3))) col,max(time1) time,name
from tb group by DATE_FORMAT(time1, '%Y-%m-%d'))b
set time4=b.col
where a.name=b.name and a.time1=b.time;
select * from tb;

 

 

 

---以下为运行过程------------------------------


mysql> create table IF NOT EXISTS tb (Name varchar(10),Time1 datetime,Time2 date
time,Time3 varchar(8),Time4 varchar(8) );
Query OK, 0 rows affected (0.03 sec)

mysql> insert tb (name,time1,time2)
    -> select '1','2010-08-04  05:06:26 ','2010-08-04  05:06:29 ' union all
    -> select '1','2010-08-04  05:06:33 ','2010-08-04  09:53:32 ' union all
    -> select '1','2010-08-04  06:06:26 ','2010-08-04  07:06:29 ' union all
    -> select '1','2010-08-05  09:43:10 ','2010-08-05  12:43:50 ' union all
    -> select '1','2010-08-05  05:43:56 ','2010-08-05  07:23:33 ' union all
    -> select '1','2010-08-06  09:43:56 ','2010-08-06  14:55:59 ' union all
    -> select '1','2010-08-07  09:04:56 ','2010-08-07  17:43:56 ' union all
    -> select '1','2010-08-08  08:56:10 ',null;
Query OK, 8 rows affected (0.00 sec)
Records: 8  Duplicates: 0  Warnings: 0

mysql>
mysql> update tb set time3=timediff(time2,time1);
Query OK, 7 rows affected (0.00 sec)
Rows matched: 8  Changed: 7  Warnings: 0

mysql> select * from tb;
+------+---------------------+---------------------+----------+-------+
| Name | Time1               | Time2               | Time3    | Time4 |
+------+---------------------+---------------------+----------+-------+
| 1    | 2010-08-04 05:06:26 | 2010-08-04 05:06:29 | 00:00:03 | NULL  |
| 1    | 2010-08-04 05:06:33 | 2010-08-04 09:53:32 | 04:46:59 | NULL  |
| 1    | 2010-08-04 06:06:26 | 2010-08-04 07:06:29 | 01:00:03 | NULL  |
| 1    | 2010-08-05 09:43:10 | 2010-08-05 12:43:50 | 03:00:40 | NULL  |
| 1    | 2010-08-05 05:43:56 | 2010-08-05 07:23:33 | 01:39:37 | NULL  |
| 1    | 2010-08-06 09:43:56 | 2010-08-06 14:55:59 | 05:12:03 | NULL  |
| 1    | 2010-08-07 09:04:56 | 2010-08-07 17:43:56 | 08:39:00 | NULL  |
| 1    | 2010-08-08 08:56:10 | NULL                | NULL     | NULL  |
+------+---------------------+---------------------+----------+-------+
8 rows in set (0.00 sec)

mysql>
mysql> update tb a,
    -> (select SEC_TO_TIME(sum(TIME_TO_SEC(time3))) col,max(time1) time,name
    -> from tb group by DATE_FORMAT(time1, '%Y-%m-%d'))b
    -> set time4=b.col
    -> where a.name=b.name and a.time1=b.time;
Query OK, 4 rows affected (0.00 sec)
Rows matched: 5  Changed: 4  Warnings: 0

mysql> select * from tb;
+------+---------------------+---------------------+----------+----------+
| Name | Time1               | Time2               | Time3    | Time4    |
+------+---------------------+---------------------+----------+----------+
| 1    | 2010-08-04 05:06:26 | 2010-08-04 05:06:29 | 00:00:03 | NULL     |
| 1    | 2010-08-04 05:06:33 | 2010-08-04 09:53:32 | 04:46:59 | NULL     |
| 1    | 2010-08-04 06:06:26 | 2010-08-04 07:06:29 | 01:00:03 | 05:47:05 |
| 1    | 2010-08-05 09:43:10 | 2010-08-05 12:43:50 | 03:00:40 | 04:40:17 |
| 1    | 2010-08-05 05:43:56 | 2010-08-05 07:23:33 | 01:39:37 | NULL     |
| 1    | 2010-08-06 09:43:56 | 2010-08-06 14:55:59 | 05:12:03 | 05:12:03 |
| 1    | 2010-08-07 09:04:56 | 2010-08-07 17:43:56 | 08:39:00 | 08:39:00 |
| 1    | 2010-08-08 08:56:10 | NULL                | NULL     | NULL     |
+------+---------------------+---------------------+----------+----------+
8 rows in set (0.00 sec)

mysql>

 

总结:

      在写这段代码前,好了sql server的。但是转到mysql里始终不能成功,在不断的看帮助、查资料、测试后发现mysql的update的一些特点

 

1、update 时,更新的表不能在set和where中用于子查询;

2、update 时,可以对多个表进行更新(sqlserver不行);

         如:update ta a,tb b set a.Bid=b.id ,b.Aid=a.id;  

3、update 后面可以做任意的查询,这个作用等同于from;

### 使用带有子查询UPDATE 语句 在 MySQL 中,`UPDATE` 语句可以结合 `JOIN` 或者嵌套子查询实现复杂的数据更新逻辑。然而需要注意的是,在同一个表内执行先读取再更新的操作时存在限制[^1]。 #### 更新单个字段的情况 当目标是从另一张表获取值并用于更新当前表的一个或多个字段时,可以通过如下方式: ```sql UPDATE table_name AS t1 SET column_to_update = ( SELECT value_column FROM another_table WHERE some_condition AND t1.id = another_table.ref_id ) WHERE EXISTS (SELECT * FROM another_table WHERE some_condition AND t1.id = another_table.ref_id); ``` 此方法适用于简单的基于单一条件匹配场景下的跨表更新操作[^3]。 #### 复杂条件下多字段更新 对于更复杂的业务需求,比如需要依据关联关系同时修改多个字段,则推荐采用 `JOIN` 的形式来进行批量更新: ```sql UPDATE table_a a INNER JOIN table_b b ON a.common_field = b.matching_field SET a.column_1 = b.source_value, a.column_2 = CASE WHEN condition THEN expression ELSE default END; ``` 这种方式不仅提高了效率而且增强了可维护性和清晰度[^2]。 #### 解决分页更新的问题 针对某些特殊的需求如需按批次处理大量记录时,虽然直接使用 `LIMIT` 可能会导致语法错误[^4],但可通过引入辅助变量或其他技巧绕过这一限制: ```sql SET @row_number := 0; UPDATE mytable m JOIN ( SELECT id, (@row_number:=@row_number + 1) as row_num FROM mytable ORDER BY sort_key ASC LIMIT 100 OFFSET 500 ) subq ON m.id = subq.id SET m.status = 'processed'; ``` 上述例子展示了如何利用用户定义变量配合子查询完成带偏移量的结果集更新任务。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值