MySQL中update语句的深入分析
MySQL利用update语句更新表中的数据,update命令的格式如下:
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name [join tbl_name2 on tbl_name.col_name=tbl_name2.col_name]
SET col_name1=expr1 [, col_name2=expr2 ...]
[WHERE where_definition]
[ORDER BY ...]
[LIMIT row_count]
说明:
(1)tbl_name:要更新的表名;
(2)SET:指定要更新的字段;
(4)join:利用另一张表的数据更新当前表的数据;
(3)WHERE:通过条件指定要更新的行,如果省略WHERE子句,则更新所有的行;
(4)ORDER BY:按照被指定的顺序对行进行更新;
(5)LIMIT:限制更新的行数;
(6)IGNORE:在更新过程中出现错误,更新语句也不会中断。
注意:
(1)更新的数据必须满足表的约束条件;
(2)提供的数据必须与字段的数据类型匹配。
一、数据准备
创建emp(员工)表,并输入数据,代码如下:
create table emp(
emp_id int primary key auto_increment comment '员工号',
emp_name char(20) not null default '' comment '员工姓名',
gender char(2) not null default '男' comment '性别',
birth datetime not null default '1990-1-1' comment '出生日期',
salary decimal(10,2) not null default 0 comment '工资',
address varchar(200) not null default '' comment '通讯地址',
dept_name char(20) comment '部门'
);
insert into emp(emp_name,gender,birth,salary,address,dept_name)
values('张晓红','女','1980-1-23',5800,'河南省郑州市中原路10号','销售部'),
('张静静','女','1987-10-3',5400,'河南省新乡市平原路38号','销售部'),
('王云飞','男','1992-11-15',5600,'河南省新乡市人民路28号','销售部'),
('王鹏飞','男','1987-10-1',6800,'河南省新乡市东明大道12号','销售部'),
('王大鹏','男','1989-2-11',5900,'河南省郑州市东风路15号','销售部'),
('王萌萌','女','1986-12-30',5000,'河南省开封市五一路14号','财务部'),
('王大光','男','1988-11-8',6200,'河南省开封市八一路124号','财务部'),
('王小明','男','1998-1-3',4800,'河南省驻马店市雪松路128号','财务部'),
('王娜娜','女','1994-3-5',5200,'河南省驻马店市车站路2号','人事部'),
('刘云飞','男','1992-8-13',6800,'河南省南阳市民生路255号','人事部'),
('张陆军','男','1991-9-6',6200,'河南省南阳市张仲景路14号','人事部');
二、update命令的基本用法
mysql> select * from emp;
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| 1 | 张晓红 | 女 | 1980-01-23 00:00:00 | 5800.00 | 河南省郑州市中原路10号 | 销售部 |
| 2 | 张静静 | 女 | 1987-10-03 00:00:00 | 5400.00 | 河南省新乡市平原路38号 | 销售部 |
| 3 | 王云飞 | 男 | 1992-11-15 00:00:00 | 5600.00 | 河南省新乡市人民路28号 | 销售部 |
| 4 | 王鹏飞 | 男 | 1987-10-01 00:00:00 | 6800.00 | 河南省新乡市东明大道12号 | 销售部 |
| 5 | 王大鹏 | 男 | 1989-02-11 00:00:00 | 5900.00 | 河南省郑州市东风路15号 | 销售部 |
| 6 | 王萌萌 | 女 | 1986-12-30 00:00:00 | 5000.00 | 河南省开封市五一路14号 | 财务部 |
| 7 | 王大光 | 男 | 1988-11-08 00:00:00 | 6200.00 | 河南省开封市八一路124号 | 财务部 |
| 8 | 王小明 | 男 | 1998-01-03 00:00:00 | 4800.00 | 河南省驻马店市雪松路128号 | 财务部 |
| 9 | 王娜娜 | 女 | 1994-03-05 00:00:00 | 5200.00 | 河南省驻马店市车站路2号 | 人事部 |
| 10 | 刘云飞 | 男 | 1992-08-13 00:00:00 | 6800.00 | 河南省南阳市民生路255号 | 人事部 |
| 11 | 张陆军 | 男 | 1991-09-06 00:00:00 | 6200.00 | 河南省南阳市张仲景路14号 | 人事部 |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
11 rows in set (0.00 sec)
mysql> update emp set salary=salary+1000; ---所有员工的工资增加1000元
Query OK, 11 rows affected (0.00 sec)
Rows matched: 11 Changed: 11 Warnings: 0
mysql> select * from emp;
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| 1 | 张晓红 | 女 | 1980-01-23 00:00:00 | 6800.00 | 河南省郑州市中原路10号 | 销售部 |
| 2 | 张静静 | 女 | 1987-10-03 00:00:00 | 6400.00 | 河南省新乡市平原路38号 | 销售部 |
| 3 | 王云飞 | 男 | 1992-11-15 00:00:00 | 6600.00 | 河南省新乡市人民路28号 | 销售部 |
| 4 | 王鹏飞 | 男 | 1987-10-01 00:00:00 | 7800.00 | 河南省新乡市东明大道12号 | 销售部 |
| 5 | 王大鹏 | 男 | 1989-02-11 00:00:00 | 6900.00 | 河南省郑州市东风路15号 | 销售部 |
| 6 | 王萌萌 | 女 | 1986-12-30 00:00:00 | 6000.00 | 河南省开封市五一路14号 | 财务部 |
| 7 | 王大光 | 男 | 1988-11-08 00:00:00 | 7200.00 | 河南省开封市八一路124号 | 财务部 |
| 8 | 王小明 | 男 | 1998-01-03 00:00:00 | 5800.00 | 河南省驻马店市雪松路128号 | 财务部 |
| 9 | 王娜娜 | 女 | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号 | 人事部 |
| 10 | 刘云飞 | 男 | 1992-08-13 00:00:00 | 7800.00 | 河南省南阳市民生路255号 | 人事部 |
| 11 | 张陆军 | 男 | 1991-09-06 00:00:00 | 7200.00 | 河南省南阳市张仲景路14号 | 人事部 |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
11 rows in set (0.00 sec)
mysql> update emp set salary=salary+1000 where dept_name='财务部'; ---'财务部'员工的工资增加1000元
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from emp;
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| 1 | 张晓红 | 女 | 1980-01-23 00:00:00 | 6800.00 | 河南省郑州市中原路10号 | 销售部 |
| 2 | 张静静 | 女 | 1987-10-03 00:00:00 | 6400.00 | 河南省新乡市平原路38号 | 销售部 |
| 3 | 王云飞 | 男 | 1992-11-15 00:00:00 | 6600.00 | 河南省新乡市人民路28号 | 销售部 |
| 4 | 王鹏飞 | 男 | 1987-10-01 00:00:00 | 7800.00 | 河南省新乡市东明大道12号 | 销售部 |
| 5 | 王大鹏 | 男 | 1989-02-11 00:00:00 | 6900.00 | 河南省郑州市东风路15号 | 销售部 |
| 6 | 王萌萌 | 女 | 1986-12-30 00:00:00 | 7000.00 | 河南省开封市五一路14号 | 财务部 |
| 7 | 王大光 | 男 | 1988-11-08 00:00:00 | 8200.00 | 河南省开封市八一路124号 | 财务部 |
| 8 | 王小明 | 男 | 1998-01-03 00:00:00 | 6800.00 | 河南省驻马店市雪松路128号 | 财务部 |
| 9 | 王娜娜 | 女 | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号 | 人事部 |
| 10 | 刘云飞 | 男 | 1992-08-13 00:00:00 | 7800.00 | 河南省南阳市民生路255号 | 人事部 |
| 11 | 张陆军 | 男 | 1991-09-06 00:00:00 | 7200.00 | 河南省南阳市张仲景路14号 | 人事部 |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
11 rows in set (0.00 sec)
select * from emp order by salary desc;
update emp set salary=salary+2000 order by salary desc limit 2;
三、update命令的使用技巧
(一)使用order by和limit更新特定记录
mysql> select * from emp order by salary desc;
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| 7 | 王大光 | 男 | 1988-11-08 00:00:00 | 8200.00 | 河南省开封市八一路124号 | 财务部 |
| 4 | 王鹏飞 | 男 | 1987-10-01 00:00:00 | 7800.00 | 河南省新乡市东明大道12号 | 销售部 |
| 10 | 刘云飞 | 男 | 1992-08-13 00:00:00 | 7800.00 | 河南省南阳市民生路255号 | 人事部 |
| 11 | 张陆军 | 男 | 1991-09-06 00:00:00 | 7200.00 | 河南省南阳市张仲景路14号 | 人事部 |
| 6 | 王萌萌 | 女 | 1986-12-30 00:00:00 | 7000.00 | 河南省开封市五一路14号 | 财务部 |
| 5 | 王大鹏 | 男 | 1989-02-11 00:00:00 | 6900.00 | 河南省郑州市东风路15号 | 销售部 |
| 1 | 张晓红 | 女 | 1980-01-23 00:00:00 | 6800.00 | 河南省郑州市中原路10号 | 销售部 |
| 8 | 王小明 | 男 | 1998-01-03 00:00:00 | 6800.00 | 河南省驻马店市雪松路128号 | 财务部 |
| 3 | 王云飞 | 男 | 1992-11-15 00:00:00 | 6600.00 | 河南省新乡市人民路28号 | 销售部 |
| 2 | 张静静 | 女 | 1987-10-03 00:00:00 | 6400.00 | 河南省新乡市平原路38号 | 销售部 |
| 9 | 王娜娜 | 女 | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号 | 人事部 |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
11 rows in set (0.00 sec)
mysql> update emp set salary=salary+2000 order by salary desc limit 2;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from emp order by salary desc;
+--------+-----------+--------+---------------------+----------+--------------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+----------+--------------------------------------+-----------+
| 7 | 王大光 | 男 | 1988-11-08 00:00:00 | 10200.00 | 河南省开封市八一路124号 | 财务部 |
| 4 | 王鹏飞 | 男 | 1987-10-01 00:00:00 | 9800.00 | 河南省新乡市东明大道12号 | 销售部 |
| 10 | 刘云飞 | 男 | 1992-08-13 00:00:00 | 7800.00 | 河南省南阳市民生路255号 | 人事部 |
| 11 | 张陆军 | 男 | 1991-09-06 00:00:00 | 7200.00 | 河南省南阳市张仲景路14号 | 人事部 |
| 6 | 王萌萌 | 女 | 1986-12-30 00:00:00 | 7000.00 | 河南省开封市五一路14号 | 财务部 |
| 5 | 王大鹏 | 男 | 1989-02-11 00:00:00 | 6900.00 | 河南省郑州市东风路15号 | 销售部 |
| 1 | 张晓红 | 女 | 1980-01-23 00:00:00 | 6800.00 | 河南省郑州市中原路10号 | 销售部 |
| 8 | 王小明 | 男 | 1998-01-03 00:00:00 | 6800.00 | 河南省驻马店市雪松路128号 | 财务部 |
| 3 | 王云飞 | 男 | 1992-11-15 00:00:00 | 6600.00 | 河南省新乡市人民路28号 | 销售部 |
| 2 | 张静静 | 女 | 1987-10-03 00:00:00 | 6400.00 | 河南省新乡市平原路38号 | 销售部 |
| 9 | 王娜娜 | 女 | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号 | 人事部 |
+--------+-----------+--------+---------------------+----------+--------------------------------------+-----------+
11 rows in set (0.00 sec)
(二)使用join关键字用其他表的数据更新当前表
举例:
create table stu(stu_id int primary key,
stu_name char(20) not null default '',
certificate_no char(20) not null default ''
);
insert into stu(stu_id,stu_name) values(10001,'张晓云'),(10002,'王云飞'),
(10003,'李大鹏'),(10004,'王大刚'),(10005,'张小倩'),(10006,'刘明明');
create table certificate(stu_id int primary key,
certificate_type char(50) not null default '',
certificate_no char(20) not null default ''
);
insert into certificate(stu_id,certificate_type,certificate_no)
values(10001,'计算机二级office高级应用','Comp-2-25879'),
(10002,'计算机三级网络技术','Comp-3-25666'),
(10003,'英语四级','CET-4-12458'),
(10005,'英语四级','CET-4-55888');
--把certificate表中的证书编号填写到学生表中。
mysql> update stu s inner join certificate c on s.stu_id=c.stu_id
-> set s.certificate_no=c.certificate_no;
Query OK, 4 rows affected (0.01 sec)
Rows matched: 4 Changed: 4 Warnings: 0
mysql> select * from stu;
+--------+-----------+----------------+
| stu_id | stu_name | certificate_no |
+--------+-----------+----------------+
| 10001 | 张晓云 | Comp-2-25879 |
| 10002 | 王云飞 | Comp-3-25666 |
| 10003 | 李大鹏 | CET-4-12458 |
| 10004 | 王大刚 | |
| 10005 | 张小倩 | CET-4-55888 |
| 10006 | 刘明明 | |
+--------+-----------+----------------+
6 rows in set (0.00 sec)
(三)使用子查询用其他表的数据更新当前表
mysql> update stu set certificate_no='';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 6 Changed: 4 Warnings: 0
mysql> select * from stu;
+--------+-----------+----------------+
| stu_id | stu_name | certificate_no |
+--------+-----------+----------------+
| 10001 | 张晓云 | |
| 10002 | 王云飞 | |
| 10003 | 李大鹏 | |
| 10004 | 王大刚 | |
| 10005 | 张小倩 | |
| 10006 | 刘明明 | |
+--------+-----------+----------------+
6 rows in set (0.00 sec)
mysql> update stu set stu.certificate_no=
-> (select certificate.certificate_no from certificate where certificate.stu_id=stu.stu_id)
-> where exists (select 1 from certificate where certificate.stu_id=stu.stu_id);
Query OK, 4 rows affected (0.01 sec)
Rows matched: 4 Changed: 4 Warnings: 0
mysql> select * from stu;
+--------+-----------+----------------+
| stu_id | stu_name | certificate_no |
+--------+-----------+----------------+
| 10001 | 张晓云 | Comp-2-25879 |
| 10002 | 王云飞 | Comp-3-25666 |
| 10003 | 李大鹏 | CET-4-12458 |
| 10004 | 王大刚 | |
| 10005 | 张小倩 | CET-4-55888 |
| 10006 | 刘明明 | |
+--------+-----------+----------------+
6 rows in set (0.00 sec)
四、update使用中的误区
(一)一个update命令对一个字段多次更新
mysql> select * from emp where emp_id=9;
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
| 9 | 王娜娜 | 女 | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号 | 人事部 |
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
1 row in set (0.00 sec)
mysql> update emp set salary=salary-3000,salary=salary+4000 where emp_id=9;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from emp where emp_id=9;
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
| 9 | 王娜娜 | 女 | 1994-03-05 00:00:00 | 7200.00 | 河南省驻马店市车站路2号 | 人事部 |
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
1 row in set (0.00 sec)
说明:此命令相当于针对salary字段执行了两次更新。
(二)一次更新多个字段必须用逗号隔开,不能使用and连接
mysql> select * from emp where emp_id=7;
+--------+-----------+--------+---------------------+----------+-----------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+----------+-----------------------------------+-----------+
| 7 | 王大光 | 男 | 1988-11-08 00:00:00 | 10200.00 | 河南省开封市八一路124号 | 财务部 |
+--------+-----------+--------+---------------------+----------+-----------------------------------+-----------+
1 row in set (0.00 sec)
mysql> update emp set salary=5800 and birth='1988-10-1' and address='河南省开封市红旗路60号' where emp_id=7;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from emp where emp_id=7;
+--------+-----------+--------+---------------------+--------+-----------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+--------+-----------------------------------+-----------+
| 7 | 王大光 | 男 | 1988-11-08 00:00:00 | 0.00 | 河南省开封市八一路124号 | 财务部 |
+--------+-----------+--------+---------------------+--------+-----------------------------------+-----------+
1 row in set (0.01 sec)
--该命令不能对emp表正确更新的原因是:把salary=后面的内容理解为一个逻辑表达式,
--返回逻辑值假(0),所以更新的结果为salary为0,即:
mysql> update emp set salary=(5800 and birth='1988-10-1', address='河南省开封市红旗路60号') where emp_id=7;
--正确的写法应该是:
mysql> update emp set salary=5800, birth='1988-10-1', address='河南省开封市红旗路60号' where emp_id=7;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from emp where emp_id=7;
+--------+-----------+--------+---------------------+---------+----------------------------------+-----------+
| emp_id | emp_name | gender | birth | salary | address | dept_name |
+--------+-----------+--------+---------------------+---------+----------------------------------+-----------+
| 7 | 王大光 | 男 | 1988-10-01 00:00:00 | 5800.00 | 河南省开封市红旗路60号 | 财务部 |
+--------+-----------+--------+---------------------+---------+----------------------------------+-----------+
1 row in set (0.00 sec)