MySQL数据库update



比如:


update db_product.tbl_product_sku ku ,
(select
  product_spec_number,
  buy_number #购买数量
from tbl_order_product op #订单商品表(表一订单下会有多个商品)
where exists(select order_id
             from tbl_order o
             where order_status = 1 and create_time >= '2018-04-28 00:00:00' and o.order_id = op.order_id)) mm 
set ku.stock = (ku.stock + mm.buy_number)
where ku.product_spec_number = mm.product_spec_number ;

?
1
2
3
4
UPDATE test.tb_vobile a
set a.name = '111 '
WHERE
a.id = (select max(id) id from test.tb_vobile)

报错:

?
1
2
3
4
5
6
7
[SQL]UPDATE test.tb_vobile a
set a.name = '111 '
WHERE
a.id = (select max(id) id from test.tb_vobile)
 
 
[Err] 1093 - You can 't specify target table ' a' for update in FROM clause

 

以下可通过:

?
1
2
3
4
5
6
7
8
9
10
11
UPDATE test.tb_vobile a
join
(select max(id) id from test.tb_vobile) b
on a.id = b.id
set a.name = '123 ' ;
 
UPDATE test.tb_vobile a ,(select max(id) id from test.tb_vobile) b
set a.name = '321 '
WHERE
a.id = b.id ;

说明:

1、update 时,更新的表不能在set和where中用于子查询;
2、update 时,可以对多个表进行更新(sqlserver不行);
如:update ta a,tb b set a.Bid=b.id ,b.Aid=a.id;

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


-------------------------------------------------------------------------------------

有两个表:SPEC1、tmpDOT
SPEC1种一列为:HIGH
tmpDOT共有两个:OLD、NEW
两个表的内容大概如下:
SPEC1:
... HIGH ...
... A    ...
... B    ...
... A    ...
... C    ...
... B    ...
... D    ...

tmpDOT:
OLD   NEW
A     newA
B     newB

C     newC

方法一

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. update a set HIGH=b.NEW  from SPEC1 a,tmpDOT  b   
  2. where a.high=b.old  


方法二

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. UPDATE A  
  2. SET HIGH=B.NEW  
  3. FROM A LEFT JOIN B ON (A.HIGH=B.OLD)  


一个复杂的栗子:一个更新多个字段的例子


UPDATE A JOIN B ON A.XX= B.XX

SET A.Y = B.Y,   A.Z=B.Z


[sql]  view plain  copy
  1. -- 正式版本 最终版 统计上班排名和时间  
  2.     UPDATE mobile_user_total AS old   
  3.     INNER JOIN   
  4.         (  
  5.             SELECT u_info.user_id, class.class_name, u_info.`name`, a.clock_date AS arrive_time, COUNT(b.user_id)+1 AS up_rank  
  6.             FROM user_info u_info   
  7.             JOIN user_class u_class ON u_info.user_id = u_class.user_id  
  8.             JOIN class ON class.id = u_class.class_id  
  9.             JOIN   
  10.                     # a 表作为考勤主表用来统计用户没有迟到的最早记录  
  11.                     (  
  12.                     SELECT u_clock.user_id, MIN(clock_date) AS clock_date, u_class.class_id  
  13.                     FROM user_clockrecords u_clock  
  14.                     JOIN user_class u_class ON u_class.user_id = u_clock.user_id  
  15.                     JOIN class ON u_class.class_id = class.id  
  16.                     WHERE DATE(clock_date) = cal_date AND DATE_FORMAT(u_clock.clock_date,'%H:%i:%s') < DATE_FORMAT(class.begin_time,'%H:%i:%s')  #根据传入的日期  
  17.                     GROUP BY user_id  
  18.                     )AS a ON u_info.user_id = a.user_id   
  19.                     LEFT JOIN(  
  20.                     SELECT u_clock.user_id, MIN(clock_date) AS clock_date, u_class.class_id  
  21.                     FROM user_clockrecords u_clock  
  22.                     JOIN user_class u_class ON u_class.user_id = u_clock.user_id  
  23.                     JOIN class ON u_class.class_id = class.id  
  24.                     WHERE DATE(clock_date) = cal_date AND DATE_FORMAT(u_clock.clock_date,'%H:%i:%s') < DATE_FORMAT(class.begin_time,'%H:%i:%s')  #根据传入的日期  
  25.                 GROUP BY user_id  
  26.                 )AS b ON a.class_id = b.class_id AND u_info.user_id <> b.user_id AND b.clock_date < a.clock_date  
  27.             GROUP BY u_info.user_id  
  28.         )AS new ON old.user_id = new.user_id AND old.`current_time` = cal_date      #根据传入的日期  
  29.     SET old.work_clock_time = new.arrive_time, old.up_ranking = new.up_rank;  



方法三

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. update  a  
  2.   set high  = (select new from tmpdot where old=a.high  )  
  3.    from spec1 a  


----------------------------------------------------------------------

首先,单表的UPDATE语句:

UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
SET col_name1=expr1 [, col_name2=expr2 ...]
[WHERE where_definition]
[ORDER BY ...]
[LIMIT row_count]

其次,多表的UPDATE语句:
 

UPDATE [LOW_PRIORITY] [IGNORE] table_references
SET col_name1=expr1 [, col_name2=expr2 ...]
[WHERE where_definition]

UPDATE语法可以用新值更新原有表行中的各列。

SET子句指示要修改哪些列和要给予哪些值。WHERE子句指定应更新哪些行。
如果没有WHERE子句,则更新所有的行。如果指定了ORDER BY子句,则按照被指定的顺序对行进行更新。
LIMIT子句用于给定一个限值,限制可以被更新的行的数目。

UPDATE语句支持以下修饰符:

1,如果您使用LOW_PRIORITY关键词,则UPDATE的执行被延迟了,直到没有其它的客户端从表中读取为止。

2,如果您使用IGNORE关键词,则即使在更新过程中出现错误,更新语句也不会中断。
如果出现了重复关键字冲突,则这些行不会被更新。如果列被更新后,新值会导致数据转化错误,则这些行被更新为最接近的合法的值。

如果您在一个表达式中通过tbl_name访问一列,则UPDATE使用列中的当前值。

例如,把年龄列设置为比当前值多一:
 

复制代码代码如下:
mysql> UPDATE persondata SET age=age+1;

 
UPDATE赋值被从左到右评估。

例如,对年龄列加倍,然后再进行增加:
 

复制代码代码如下:
mysql> UPDATE persondata SET age=age*2, age=age+1;

 
如果您把一列设置为其当前含有的值,则MySQL会注意到这一点,但不会更新。

如果您把被已定义为NOT NULL的列更新为NULL,则该列被设置到与列类型对应的默认值,并且累加警告数。
对于数字类型,默认值为0;对于字符串类型,默认值为空字符串('');对于日期和时间类型,默认值为“zero”值。

UPDATE会返回实际被改变的行的数目。Mysql_info() C API函数可以返回被匹配和被更新的行的数目,以及在UPDATE过程中产生的警告的数量。

您可以使用LIMIT row_count来限定UPDATE的范围。LIMIT子句是一个与行匹配的限定。
只要发现可以满足WHERE子句的row_count行,则该语句中止,不论这些行是否被改变。

如果一个UPDATE语句包括一个ORDER BY子句,则按照由子句指定的顺序更新行。

您也可以执行包括多个表的UPDATE操作。table_references子句列出了在联合中包含的表。

例子:

复制代码代码如下:

SQL>UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;

说明:以上代码显示出了使用逗号操作符的内部联合,但是multiple-table UPDATE语句可以使用在SELECT语句中允许的任何类型的联合,比如LEFT JOIN。

注释:不能把ORDER BY或LIMIT与multiple-table UPDATE同时使用。

在一个被更改的multiple-table UPDATE中,有些列被引用。您只需要这些列的UPDATE权限。有些列被读取了,但是没被修改。您只需要这些列的SELECT权限。

如果您使用的multiple-table UPDATE语句中包含带有外键限制的InnoDB表,则MySQL优化符处理表的顺序可能与上下层级关系的顺序不同。

在此情况下,语句无效并被 回滚。同时,更新一个单一表,并且依靠ON UPDATE功能。
该功能由InnoDB提供,用于对其它表进行相应的修改。

目前,不能在一个子查询中更新一个表,同时从同一个表中选择。

update语句的几种基本用法

A. 使用简单的 UPDATE

下列示例说明如果从 UPDATE 语句中去除 WHERE 子句,所有的行会受到什么影响。

下面这个例子说明,如果表 publishers 中的所有出版社将总部搬迁到佐治亚州的亚特兰大市,表 publishers 如何更新。

复制代码代码如下:

UPDATE publishers
SET city = 'Atlanta', state = 'GA'

本示例将所有出版商的名字变为 NULL。

复制代码代码如下:

UPDATE publishers
SET pub_name = NULL

也可以在更新中使用计算值。本示例将表 titles 中的所有价格加倍。

复制代码代码如下:

UPDATE titles
SET price = price * 2

B.把 WHERE 子句和 UPDATE 语句一起使用
WHERE 子句指定要更新的行例如,在下面这个虚构的事件中,北加利福尼亚更名为 Pacifica(缩写为 PC),而奥克兰的市民投票决定将其城市的名字改为 Bay City。这个例子说明如何为奥克兰市以前的所有居民(他们的地址已经过时)更新表 authors。

复制代码代码如下:

UPDATE authors
    SET state = 'PC', city = 'Bay City'
       WHERE state = 'CA' AND city = 'Oakland'

必须编写另一个语句来更改北加利福尼亚其它城市的居民所在的州名。

C.通过 UPDATE 语句使用来自另一个表的信息
本示例修改表 titles 中的 ytd_sales 列,以反映表 sales 中的最新销售记录。

复制代码代码如下:

UPDATE titles
    SET ytd_sales = titles.ytd_sales + sales.qty
       FROM titles, sales
          WHERE titles.title_id = sales.title_id
          AND sales.ord_date = (SELECT MAX(sales.ord_date) FROM sales)

这个例子假定,一种特定的商品在特定的日期只记录一批销售量,而且更新是最新的。如果不是这样(即如果一种特定的商品在同一天可以记录不止一批销售量),这里所示的例子将出错。例子可正确执行,但是每种商品只用一批销售量进行更新,而不管那一天实际销售了多少批。这是因为一个 UPDATE 语句从不会对同一行更新两次。

对于特定的商品在同一天可销售不止一批的情况,每种商品的所有销售量必须在 UPDATE 语句中合计在一起,如下例所示:

复制代码代码如下:

UPDATE titles
    SET ytd_sales = 
       (SELECT SUM(qty)
          FROM sales
             WHERE sales.title_id = titles.title_id
             AND sales.ord_date IN (SELECT MAX(ord_date) FROM sales))
    FROM titles, sales

D. 将 UPDATE 语句与 SELECT 语句中的 TOP 子句一起使用
这个例子对来自表 authors 的前十个作者的 state 列进行更新。

复制代码代码如下:

UPDATE authors
SET state = 'ZZ' 
FROM (SELECT TOP 10 * FROM authors ORDER BY au_lname) AS t1
WHERE authors.au_id = t1.au_id

以上就是mysql update语句用法的全部内容,希望对大家有所帮助。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值