11. 数据处理之增删改
11.1 插入数据
INSERT语句向表中插入数据
VALUES的方式添加
-
为表中所有字段按默认顺序插入数据
INSERT INTO 表名 VALUES (value1,value2,.....);
每一个值对应字段默认顺序,并且需要一一对应,不能缺失
INSERT INTO departments VALUES (100, 'Finance', NULL, NULL);
-
为表中指定字段插入数据
插入的时候指定字段已经顺序
INSERT INTO 表名(字段1,字段2,...) VALUES (value1,value2,.....);
添加的值需要和指定的字段一一对应
INSERT INTO departments(department_id, department_name) VALUES (80, 'IT');
-
同时插入多条记录
VALUES后面加入多个值用
,
分隔开INSERT INTO 表名(字段1,字段2,...) VALUES (value1,value2,.....), (value1,value2,.....), ... (value1,value2,.....); # 举例 INSERT INTO emp(emp_id,emp_name) VALUES (1001,'shkstart'), (1002,'atguigu'), (1003,'Tom'); /* Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 */
● Records:表明插入的记录条数。
● Duplicates:表明插入时被忽略的记录,原因可能是这 些记录包含了重复的主键值。
● Warnings:表明有问题的数据值,例如发生数据类型转换。
一个同时插入多行记录的INSERT语句等同于多个单行插入的INSERT语句,但是多行的INSERT语句 在处理过程中 效率更高 。因为MySQL执行单条INSERT语句插入多行数据比使用多条INSERT语句 快,所以在插入多条记录时最好选择使用单条INSERT语句的方式插入。
小结
- VALUES也可以写成VALUE,但是VALUES是标准写法
- 字符和日期型数据应该包含在单引号中
查询结果插入到表中
INSERT还可以将SELECT语句查询的结果插入到表中,此时不需要把每一条记录的值一个一个输入,只需要使用一条INSERT语句和一条SELECT语句组成的组合语句即可快速地从一个或多个表中向一个表中插入 多行。
INSERT INTO 目标表名
(tar_column1 [, tar_column2, …, tar_columnn])
SELECT
(src_column1 [, src_column2, …, src_columnn])
FROM 源表名
[WHERE condition]
- INSERT语句中加入子查询
- 不用写VALUES字句
- 子查询中字段需要和INSERT中的目标表中的字段对应
INSERT INTO emp2
SELECT *
FROM employees
WHERE department_id = 90;
INSERT INTO sales_reps(id, name, salary, commission_pct)
SELECT employee_id, last_name, salary, commission_pct
FROM employees
WHERE job_id LIKE '%REP%';
11.2 更新数据
UPDATE语句更新数据
UPDATE table_name
SET column1=value1, column2=value2, … , column=valuen
[WHERE condition]
-
可以一次更新多条数据
-
如果需要回滚数据,需要保证再DML前,设置过不自动提交:SET AUTOCOMMIT = FALSE
-
使用WHERE子句指定需要更新的数据
UPDATE employees SET department_id = 70 WHERE employee_id = 113;
-
如果省略WHERE子句,表中所有数据都将被更新
UPDATE copy_emp SET department_id = 110;
-
更新中的数据完整性错误
UPDATE employees SET department_id = 55 WHERE department_id = 110;
department_id存在外键,不存在 55 号部门因此报错
11.3 删除数据
DELETE语句从表中删除数据
DELETE FROM table_name
[WHERE <condition>];
table_name指定要执行删除操作的表;“[WHERE ]”为可选参数,指定删除条件,如果没有WHERE子句, DELETE语句将删除表中的所有记录。
-
使用WHERE子句删除指定的记录
DELETE FROM departments WHERE department_name = 'Finance';
-
如果省略 WHERE 子句,则表中的全部数据将被删除
DELETE FROM copy_emp;
-
删除中的数据完整性错误
DELETE FROM departments WHERE department_id = 60;
说明:无法删除外键并且作为其他表的主键的数据
11.4 MySQL8新特性:计算列
计算列通俗的来讲就是通过其他列计算得到的数值,不需要手动插入数值
# 创建表1,字段a,字段b,其中字段c是计算列,数值为a + b
CREATE TABLE tb1(
id INT,
a INT,
b INT,
c INT GENERATED ALWAYS AS (a + b) [VIRTUAL]
);
# 插入数值
INSERT INTO tb1(a,b) VALUES (100,200);
SELECT * FROM tb1;
/*
+------+------+------+------+
| id | a | b | c |
+------+------+------+------+
| NULL | 100 | 200 | 300 |
+------+------+------+------+
1 row in set (0.00 sec)
*/
更新表中数据的时候,计算列也会被更新
11.5 练习
练习一
# 1、创建数据库test01_library
CREATE DATABASE IF NOT EXISTS test01_library;
USE test01_library;
# 2、创建表 books,表结构如下:
CREATE TABLE IF NOT EXISTS books(
id INT,
`name` VARCHAR(50),
`authors` VARCHAR(100),
price FLOAT,
pubdate YEAR,
note VARCHAR(100),
num INT
);
DESC books;
# 3、向books表中插入记录
# 1)不指定字段名称,插入第一条记录
INSERT INTO books
VALUES(1, 'Tal of AAA', 'Dickes', 23, 1995, 'novel', 11);
# 2)指定所有字段名称,插入第二记录
INSERT INTO books(id, `name`, `authors`, price, pubdate, note, num)
VALUES(2, 'EmmaT', 'Jane lura', 35, 1993, 'joke', 22);
# 3)同时插入多条记录(剩下的所有记录)
INSERT INTO books
VALUES
(3,'Story of Jane','Jane Tim',40,2001,'novel',0),
(4,'Lovey Day','George Byron',20,2005,'novel',30),
(5,'Old land','Honore Blade',30,2010,'Law',0),
(6,'The Battle','Upton Sara',30,1999,'medicine',40),
(7,'Rose Hood','Richard haggard',28,2008,'cartoon',28);
# 4、将小说类型(novel)的书的价格都增加5。
UPDATE books
SET price = price + 5
WHERE note = 'novel';
# 5、将名称为EmmaT的书的价格改为40,并将说明改为drama。
UPDATE books
SET price = 40, note='drama'
WHERE `name` = 'EmmaT';
# 6、删除库存为0的记录
DELETE FROM books
WHERE num = 0;
# 7、统计书名中包含a字母的书
SELECT * FROM books WHERE `name` LIKE '%a%';
# 8、统计书名中包含a字母的书的数量和库存总量
SELECT COUNT(*), SUM(num) FROM books WHERE `name` LIKE '%a%';
# 9、找出“novel”类型的书,按照价格降序排列
SELECT * FROM books WHERE note = 'novel' ORDER BY price DESC;
# 10、查询图书信息,按照库存量降序排列,如果库存量相同的按照note升序排列
SELECT * FROM books ORDER BY num DESC, note;
# 11、按照note分类统计书的数量
SELECT note, COUNT(*), SUM(num) FROM books GROUP BY note;
# 12、按照note分类统计书的库存量,显示库存量超过30本的
SELECT note, SUM(num) num_note FROM books GROUP BY note HAVING num_note > 30;
# 13、查询所有图书,每页显示5本,显示第二页
SELECT * FROM books LIMIT 5, 5;
# 14、按照note分类统计书的库存量,显示库存量最多的
SELECT note, SUM(num) num_note FROM books GROUP BY note ORDER BY num_note DESC LIMIT 0,1;
# 15、查询书名达到10个字符的书,不包括里面的空格
SELECT * FROM books WHERE LENGTH(REPLACE(name,' ','')) >= 10;
# 16、查询书名和类型,其中note值为novel显示小说,law显示法律,medicine显示医药,cartoon显示卡通,joke显示笑话
SELECT `name` AS '书名', note, CASE note
WHEN 'novel' THEN '小说'
WHEN 'law' THEN '法律'
WHEN 'medicine' THEN '医药'
WHEN 'cartoon' THEN '卡通'
WHEN 'joke' THEN '笑话'
END AS '类型'
FROM books;
# 17、查询书名、库存,其中num值超过30本的,显示滞销,大于0并低于10的,显示畅销,为0的显示需要无货
SELECT `name`, num, CASE
WHEN num > 30 THEN '滞销'
WHEN num > 0 AND num < 10 THEN '畅销'
WHEN num = 0 THEN '无货'
ELSE '正常'
END AS '库存'
FROM books;
# 18、统计每一种note的库存量,并合计总量
SELECT note, SUM(num)
FROM books GROUP BY note WITH ROLLUP;
SELECT IFNULL(note,'合计总库存量') AS note,SUM(num) FROM books GROUP BY note WITH
ROLLUP;
# 19、统计每一种note的数量,并合计总量
SELECT note, COUNT(*)
FROM books GROUP BY note WITH ROLLUP;
SELECT IFNULL(note,'合计总库存量') AS note,COUNT(*) FROM books GROUP BY note WITH
ROLLUP;
# 20、统计库存量前三名的图书
SELECT *
FROM books ORDER BY num DESC LIMIT 0,3;
# 21、找出最早出版的一本书
SELECT * FROM books ORDER BY pubdate ASC LIMIT 0,1;
# 22、找出novel中价格最高的一本书
SELECT *
FROM books WHERE note = 'novel' ORDER BY price DESC LIMIT 0,1;
# 23、找出书名中字数最多的一本书,不含空格
SELECT * FROm books
ORDER BY LENGTH(REPLACE(`name`,' ','')) DESC LIMIT 0,1;
练习二
#1. 创建数据库dbtest11
CREATE DATABASE IF NOT EXISTS dbtest11 CHARACTER SET 'utf8';
USE dbtest11;
#2. 运行以下脚本创建表my_employees
CREATE TABLE IF NOT EXISTS my_employees(
id INT(10),
first_name VARCHAR(10),
last_name VARCHAR(10),
userid VARCHAR(10),
salary DOUBLE(10,2)
);
CREATE TABLE IF NOT EXISTS users(
id INT,
userid VARCHAR(10),
department_id INT
);
#3. 显示表my_employees的结构
DESC my_employees;
#4. 向my_employees表中插入下列数据
/*
ID FIRST_NAME LAST_NAME USERID SALARY
1 patel Ralph Rpatel 895
2 Dancs Betty Bdancs 860
3 Biri Ben Bbiri 1100
4 Newman Chad Cnewman 750
5 Ropeburn Audrey Aropebur 1550
*/
INSERT INTO my_employees
VALUES
(1, 'patel', 'Ralph', 'Rpatel', 895),
(2, 'Dancs', 'Betty', 'Bdancs', 860),
(3, 'Biri', 'Ben', 'Bbiri', 1100),
(4, 'Newman', 'Chad', 'Cnewman', 750),
(5, 'Ropeburn', 'Audrey', 'Aropebur', 1550);
#5. 向users表中插入数据
/*
1 Rpatel 10
2 Bdancs 10
3 Bbiri 20
4 Cnewman 30
5 Aropebur 40
*/
INSERT INTO users
VALUES
(1, 'Rpatel', 10),
(2, 'Bdancs', 10),
(3, 'Bbiri', 20),
(4, 'Cnewman', 30),
(5, 'Aropebur', 40);
#6. 将3号员工的last_name修改为“drelxer”
UPDATE my_employees
SET last_name = 'drelxer'
WHERE id = 3;
#7. 将所有工资少于900的员工的工资修改为1000
UPDATE my_employees
SET salary = 1000
WHERE salary < 900;
#8. 将userid为Bbiri的user表和my_employees表的记录全部删除
DELETE u, e
FROM users u, my_employees e
WHERE u.`userid`=e.`Userid` AND u.`userid`='Bbiri';
#9. 删除my_employees、users表所有数据
DELETE FROM my_employees;
DELETE FROM users;
#10. 检查所作的修正
SELECT * FROM my_employees;
SELECT * FROM users;
#11. 清空表my_employees
TRUNCATE TABLE my_employees;
练习三
# 1. 使用现有数据库dbtest11
CREATE DATABASE IF NOT EXISTS dbtest11;
USE dbtest11;
# 2. 创建表格pet
CREATE TABLE IF NOT EXISTS pet(
`name` VARCHAR(20),
`owner` VARCHAR(20),
`species` VARCHAR(20),
`sex` VARCHAR(1),
`birth` YEAR,
`death` YEAR
);
# 3. 添加记录
INSERT INTO pet VALUES('Fluffy','harold','Cat','f','2013','2010');
INSERT INTO pet(`name`,`owner`,species,sex,Birth)
VALUES('Claws','gwen','Cat','m','2014');
INSERT INTO pet(`name`,species,sex,Birth) VALUES('Buffy','Dog','f','2009');
INSERT INTO pet(`name`,`owner`,species,sex,Birth)
VALUES('Fang','benny','Dog','m','2000');
INSERT INTO pet VALUES('bowser','diane','Dog','m','2003','2009');
INSERT INTO pet(`name`,species,sex,birth) VALUES('Chirpy','Bird','f','2008');
# 4. 添加字段:主人的生日owner_birth DATE类型。
ALTER TABLE pet ADD owner_birth DATE;
# 5. 将名称为Claws的猫的主人改为kevin
UPDATE pet SET `owner` = 'kevin' WHERE `name` = 'Claws';
# 6. 将没有死的狗的主人改为duck
UPDATE pet SET `owner` = 'duck' WHERE `species` = 'dog' AND `death` IS NULL;
# 7. 查询没有主人的宠物的名字;
SELECT `name` FROM pet WHERE `owner` IS NULL;
# 8. 查询已经死了的cat的姓名,主人,以及去世时间;
SELECT `name`, `owner`, `death` FROM pet WHERE `species` = 'cat' AND `death` IS NOT NULL;
# 9. 删除已经死亡的狗
DELETE FROM pet WHERE `species` = 'dog' AND `death` IS NOT NULL;
# 10. 查询所有宠物信息
SELECT * FROM pet;
练习四
# 1. 使用已有的数据库dbtest11
USE dbtest11;
# 2. 创建表employee,并添加记录
CREATE TABLE IF NOT EXISTS employee(
id INT,
`name` VARCHAR(20),
sex VARCHAR(2),
tel VARCHAR(20),
addr VARCHAR(50),
salary DOUBLE
);
# 添加信息
INSERT INTO employee(id,`name`,sex,tel,addr,salary)VALUES
(10001,'张一一','男','13456789000','山东青岛',1001.58),
(10002,'刘小红','女','13454319000','河北保定',1201.21),
(10003,'李四','男','0751-1234567','广东佛山',1004.11),
(10004,'刘小强','男','0755-5555555','广东深圳',1501.23),
(10005,'王艳','男','020-1232133','广东广州',1405.16);
# 3. 查询出薪资在1200~1300之间的员工信息。
SELECT * FROM employee WHERE salary BETWEEN 1200 AND 1300;
# 4. 查询出姓“刘”的员工的工号,姓名,家庭住址。
SELECT * FROM employee WHERE `name` LIKE '%刘%';
# 5. 将“李四”的家庭住址改为“广东韶关”
UPDATE employee SET addr = '广东韶关' WHERE `name` = '李四';
# 6. 查询出名字中带“小”的员工
SELECT * FROM employee WHERE `name` LIKE '%小%';