当前位置:   article > 正文

【MySQL】表的增删查改_mysql查询、添加、修改

mysql查询、添加、修改

目录

一、Creat

1.1 insert

1.2 插入否则更新

1.3 替换 replace

二、Retrieve

2.1 select

2.2 where

2.3 order by

2.4 limit

2.5 插入查询结果

2.6 聚合函数

2.7 group by 和 having

三、Update

四、Delete

4.1 delete

4.2 truncate


CRUD操作是数据库管理中的基本操作,它们分别代表以下概念

Create(创建),Retrieve(读取),Update(更新),Delete(删除)

一、Creat

1.1 insert

语法:

insert [into] 表名 [(列名...)] values (列值...)

注意:

  • into 可以省略,但不推荐,加上into看着会更直接,当然是否省略看个人习惯。
  • 列名可以不写或者选定列,如果忽略列名就是全列插入。
  • 全列插入时,列值数量必须和定义表的列的数量及顺序一致。
  • 指定列插入时,列值数量必须和SQL语句中列名的数量及顺序一致。
  • 插入时可以一次插入单行或多行数据,如果是多行就用逗号隔开。

示例:

创建一张学生表

  1. mysql> create table students(
  2. -> id int unsigned primary key auto_increment,
  3. -> sn int not null unique comment '学号',
  4. -> name varchar(20) not null,
  5. -> qq varchar(20)
  6. -> );

单行数据 + 全列插入

  1. mysql> insert into students values (1, 1001, '李白', null);
  2. Query OK, 1 row affected (0.01 sec)

多行数据 + 指定列插入

  1. mysql> insert into students (sn, name, qq) values (1002, '杜甫', '123321'),(1003, '苏轼', '11111');
  2. Query OK, 2 rows affected (0.01 sec)
  3. Records: 2 Duplicates: 0 Warnings: 0
  4. mysql> select * from students;
  5. +----+------+--------+--------+
  6. | id | sn | name | qq |
  7. +----+------+--------+--------+
  8. | 1 | 1001 | 李白 | NULL |
  9. | 2 | 1002 | 杜甫 | 123321 |
  10. | 3 | 1003 | 苏轼 | 11111 |
  11. +----+------+--------+--------+
  12. 3 rows in set (0.01 sec)

1.2 插入否则更新

在MySQL中,如果希望在插入记录时检查记录是否已存在,如果存在则更新该记录,否则插入新记录,可以使用 insert... on duplicate key update语句。这个语句结合了插入和更新的操作,适用于当表中存在唯一索引或主键约束时。

语法:

  1. INSERT INTO table_name (column1, column2, ..., columnN)
  2. VALUES (value1, value2, ..., valueN)
  3. ON DUPLICATE KEY UPDATE
  4. column1 = value1,
  5. column2 = value2,
  6. ...;

注意:插入记录时,可以检查受影响的行数来判断操作的结果。

  • 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
  • 1 row affected: 表中没有冲突数据,数据被插入
  • 2 row affected: 表中有冲突数据,并且数据已经被更新

示例:

由于主键或者唯一键对应的值已经存在而导致插入失败,选择进行更新操作。

  1. mysql> insert into students
  2. -> values (1, 1001, '李白', '10001')
  3. -> on duplicate key update
  4. -> sn = 1000,
  5. -> qq = '100001';
  6. Query OK, 2 rows affected (0.00 sec)
  7. mysql> select * from students;
  8. +----+------+--------+--------+
  9. | id | sn | name | qq |
  10. +----+------+--------+--------+
  11. | 1 | 1000 | 李白 | 100001 |
  12. | 2 | 1002 | 杜甫 | 123321 |
  13. | 3 | 1003 | 苏轼 | 11111 |
  14. +----+------+--------+--------+
  15. 3 rows in set (0.00 sec)

1.3 替换 replace

replace语句是一种特殊的SQL操作,它首先尝试插入新行,如果遇到主键或唯一键的冲突,它会先删除冲突的行,然后插入新行。replace语句实际上是一个delete和insert的组合。

语法:

replace into 表名 [(列名...)] values (列值...)

 注意:

  • 主键 或者 唯一键 没有冲突,则直接插入。
  • 主键 或者 唯一键 如果冲突,则删除后再插入。
  • 1 row affected:表中没有冲突数据,数据被插入。
  • 2 row affected:表中有冲突数据,删除后重新插入。
  1. mysql> replace into students values(3,1003, 'sushi', '111111');
  2. Query OK, 2 rows affected (0.00 sec)
  3. mysql> select * from students;
  4. +----+------+--------+--------+
  5. | id | sn | name | qq |
  6. +----+------+--------+--------+
  7. | 1 | 1000 | 李白 | 100001 |
  8. | 2 | 1002 | 杜甫 | 123321 |
  9. | 3 | 1003 | sushi | 111111 |
  10. +----+------+--------+--------+
  11. 3 rows in set (0.00 sec)

二、Retrieve

Retrieve(检索)是指从数据库中查询和获取数据的过程。在MySQL中,这是通过使用SELECT语句来实现的。

创建表结构

  1. mysql> CREATE TABLE exam_result (
  2. -> id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  3. -> name VARCHAR(20) NOT NULL COMMENT '同学姓名',
  4. -> chinese float DEFAULT 0.0 COMMENT '语文成绩',
  5. -> math float DEFAULT 0.0 COMMENT '数学成绩',
  6. -> english float DEFAULT 0.0 COMMENT '英语成绩'
  7. -> );
  8. Query OK, 0 rows affected (0.03 sec)

插入测试数据

  1. mysql> INSERT INTO exam_result (name, chinese, math, english) VALUES
  2. -> ('唐三藏', 67, 98, 56),
  3. -> ('孙悟空', 87, 78, 77),
  4. -> ('猪悟能', 88, 98, 90),
  5. -> ('曹孟德', 82, 84, 67),
  6. -> ('刘玄德', 55, 85, 45),
  7. -> ('孙权', 70, 73, 78),
  8. -> ('宋公明', 75, 65, 30);
  9. Query OK, 7 rows affected (0.00 sec)
  10. Records: 7 Duplicates: 0 Warnings: 0

2.1 select

语法:

  1. SELECT
  2. [DISTINCT] {* | {column [, column] ...}
  3. [FROM table_name]
  4. [WHERE ...]
  5. [GROUP BY column1, column2, ...]
  6. [HAVING ...]
  7. [ORDER BY column [ASC | DESC], ...]
  8. LIMIT ...

注意:

  • 操作的本质是对数据进行遍历,默认是拿整张表的信息。
  • 若指定列,就只显示那几列的信息。(还是会把整张表的数据读取)
  • select 后面可以加语句,也可以加表达式。
  • 给列名过表达式后面加上as,select显示时按照as后的别名。(as可省略)

select的执行顺序:

  1. FROM table_name: 首先确定要查询的表。
  2. WHERE …: 然后根据条件筛选表中的行。
  3. GROUP BY …: 对筛选后的数据进行分组。
  4. HAVING …: 对分组后的结果进行进一步筛选。
  5. SELECT: 选择要返回的列。
  6. DISTINCT: 如果指定了DISTINCT,则去除重复的行。
  7. ORDER BY column [ASC | DESC]: 对结果进行排序。
  8. LIMIT …: 最后,如果指定了LIMIT,则限制返回的行数。

全列查询

通常情况下不建议使用 * 进行全列查询

  1. 查询的列越多,意味着需要传输的数据量越大;
  2. 可能会影响到索引的使用。
  1. mysql> SELECT * FROM exam_result;
  2. +----+-----------+---------+------+---------+
  3. | id | name | chinese | math | english |
  4. +----+-----------+---------+------+---------+
  5. | 1 | 唐三藏 | 67 | 98 | 56 |
  6. | 2 | 孙悟空 | 87 | 78 | 77 |
  7. | 3 | 猪悟能 | 88 | 98 | 90 |
  8. | 4 | 曹孟德 | 82 | 84 | 67 |
  9. | 5 | 刘玄德 | 55 | 85 | 45 |
  10. | 6 | 孙权 | 70 | 73 | 78 |
  11. | 7 | 宋公明 | 75 | 65 | 30 |
  12. +----+-----------+---------+------+---------+
  13. 7 rows in set (0.00 sec)

指定列查询

指定列的顺序不需要按定义表的顺序来

  1. mysql> SELECT id, name, english FROM exam_result;
  2. +----+-----------+---------+
  3. | id | name | english |
  4. +----+-----------+---------+
  5. | 1 | 唐三藏 | 56 |
  6. | 2 | 孙悟空 | 77 |
  7. | 3 | 猪悟能 | 90 |
  8. | 4 | 曹孟德 | 67 |
  9. | 5 | 刘玄德 | 45 |
  10. | 6 | 孙权 | 78 |
  11. | 7 | 宋公明 | 30 |
  12. +----+-----------+---------+
  13. 7 rows in set (0.00 sec)

查询字段为表达式

  1. mysql> SELECT id, name, english + 10 FROM exam_result;
  2. +----+-----------+--------------+
  3. | id | name | english + 10 |
  4. +----+-----------+--------------+
  5. | 1 | 唐三藏 | 66 |
  6. | 2 | 孙悟空 | 87 |
  7. | 3 | 猪悟能 | 100 |
  8. | 4 | 曹孟德 | 77 |
  9. | 5 | 刘玄德 | 55 |
  10. | 6 | 孙权 | 88 |
  11. | 7 | 宋公明 | 40 |
  12. +----+-----------+--------------+
  13. 7 rows in set (0.00 sec)

表达式包含多个字段

SELECT id, name, chinese + math + english FROM exam_result;

为查询结果指定别名

语法:SELECT column [AS] alias_name [...] FROM table_name;

  • AS可省略
  1. mysql> SELECT id, name, chinese + math + english 总分 FROM exam_result;
  2. +----+-----------+--------+
  3. | id | name | 总分 |
  4. +----+-----------+--------+
  5. | 1 | 唐三藏 | 221 |
  6. | 2 | 孙悟空 | 242 |
  7. | 3 | 猪悟能 | 276 |
  8. | 4 | 曹孟德 | 233 |
  9. | 5 | 刘玄德 | 185 |
  10. | 6 | 孙权 | 221 |
  11. | 7 | 宋公明 | 170 |
  12. +----+-----------+--------+
  13. 7 rows in set (0.00 sec)

结果去重(distinct)

  1. mysql> SELECT DISTINCT math FROM exam_result;
  2. +------+
  3. | math |
  4. +------+
  5. | 98 |
  6. | 78 |
  7. | 84 |
  8. | 85 |
  9. | 73 |
  10. | 65 |
  11. +------+
  12. 6 rows in set (0.00 sec)

2.2 where

比较运算符:

逻辑运算符:

注意:

  • where 子句不能用列的别名进行条件判断。

示例: 

英语不及格的同学及英语成绩 ( < 60 )

  1. mysql> SELECT name, english FROM exam_result WHERE english < 60;
  2. +-----------+---------+
  3. | name | english |
  4. +-----------+---------+
  5. | 唐三藏 | 56 |
  6. | 刘玄德 | 45 |
  7. | 宋公明 | 30 |
  8. +-----------+---------+
  9. 3 rows in set (0.00 sec)

语文成绩在 [80, 90] 分的同学及语文成绩

  1. SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese <= 90;
  2. 或者
  3. SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;

数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩

  1. SELECT name, math FROM exam_result
  2. 或者
  3. SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);

姓孙的同学 及 孙某同学

  • % 匹配任意多个(包括 0 个)任意字符
  • _ 匹配严格的一个任意字符
  1. SELECT name FROM exam_result WHERE name LIKE '孙%';
  2. +-----------+
  3. | name |
  4. +-----------+
  5. | 孙悟空 |
  6. | 孙权 |
  7. +-----------+
  8. 2 rows in set (0.01 sec)
  9. SELECT name FROM exam_result WHERE name LIKE '孙_';
  10. +--------+
  11. | name |
  12. +--------+
  13. | 孙权 |
  14. +--------+
  15. 1 row in set (0.00 sec)

NULL 的查询

NULL 和 NULL 的比较,= 和 <=> 的区别:

  1. mysql> SELECT NULL = NULL, NULL = 1, NULL = 0;
  2. +-------------+----------+----------+
  3. | NULL = NULL | NULL = 1 | NULL = 0 |
  4. +-------------+----------+----------+
  5. | NULL | NULL | NULL |
  6. +-------------+----------+----------+
  7. 1 row in set (0.00 sec)
  8. mysql> SELECT NULL <=> NULL, NULL <=> 1, NULL <=> 0;
  9. +---------------+------------+------------+
  10. | NULL <=> NULL | NULL <=> 1 | NULL <=> 0 |
  11. +---------------+------------+------------+
  12. | 1 | 0 | 0 |
  13. +---------------+------------+------------+
  14. 1 row in set (0.00 sec)

查询 qq 号已知的同学姓名

  1. mysql> select * from students;
  2. +----+------+-----------+--------+
  3. | id | sn | name | qq |
  4. +----+------+-----------+--------+
  5. | 1 | 1000 | 李白 | 100001 |
  6. | 2 | 1002 | 杜甫 | 123321 |
  7. | 3 | 1003 | sushi | 111111 |
  8. | 4 | 1004 | 李煜 | 234561 |
  9. | 5 | 1005 | 辛弃疾 | NULL |
  10. | 6 | 1006 | 杨慎 | NULL |
  11. +----+------+-----------+--------+
  12. 6 rows in set (0.00 sec)
  13. mysql> SELECT name, qq FROM students WHERE qq IS NOT NULL;
  14. +--------+--------+
  15. | name | qq |
  16. +--------+--------+
  17. | 李白 | 100001 |
  18. | 杜甫 | 123321 |
  19. | sushi | 111111 |
  20. | 李煜 | 234561 |
  21. +--------+--------+
  22. 4 rows in set (0.00 sec)

2.3 order by

使用order by 进行结果排序。

语法:

  • ASC 为升序(从小到大)
  • DESC 为降序(从大到小)
  • 默认为 ASC
  • NULL 比任何值都小。
  • 可以使用列别名。(顺序在select之后)
  • 没有使用 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序。
  1. SELECT ... FROM table_name [WHERE ...]
  2. ORDER BY column [ASC|DESC], [...];

示例:同学及数学成绩,按数学成绩升序显示

  1. mysql> SELECT name, math FROM exam_result ORDER BY math;
  2. +-----------+------+
  3. | name | math |
  4. +-----------+------+
  5. | 宋公明 | 65 |
  6. | 孙权 | 73 |
  7. | 孙悟空 | 78 |
  8. | 曹孟德 | 84 |
  9. | 刘玄德 | 85 |
  10. | 唐三藏 | 98 |
  11. | 猪悟能 | 98 |
  12. +-----------+------+
  13. 7 rows in set (0.00 sec)

2.4 limit

limit 用于筛选分页结果,语法如下:

  1. -- 起始下标为 0
  2. -- 从 s 开始,筛选 n 条结果
  3. SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n;
  4. -- 从 0 开始,筛选 n 条结果
  5. SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;
  6. -- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
  7. SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;

注意:

  • 对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死。

示例:

按 id 进行分页,每页 3 条记录,分别显示 第 1、2、3 页

  1. mysql> SELECT id, name, math, english, chinese FROM exam_result
  2. -> ORDER BY id LIMIT 3 OFFSET 0;
  3. +----+-----------+------+---------+---------+
  4. | id | name | math | english | chinese |
  5. +----+-----------+------+---------+---------+
  6. | 1 | 唐三藏 | 98 | 56 | 67 |
  7. | 2 | 孙悟空 | 78 | 77 | 87 |
  8. | 3 | 猪悟能 | 98 | 90 | 88 |
  9. +----+-----------+------+---------+---------+
  10. 3 rows in set (0.00 sec)
  11. mysql> SELECT id, name, math, english, chinese FROM exam_result
  12. -> ORDER BY id LIMIT 3 OFFSET 3;
  13. +----+-----------+------+---------+---------+
  14. | id | name | math | english | chinese |
  15. +----+-----------+------+---------+---------+
  16. | 4 | 曹孟德 | 84 | 67 | 82 |
  17. | 5 | 刘玄德 | 85 | 45 | 55 |
  18. | 6 | 孙权 | 73 | 78 | 70 |
  19. +----+-----------+------+---------+---------+
  20. 3 rows in set (0.00 sec)

2.5 插入查询结果

将查询结果插入到另一个表中,可以使用INSERT INTO ... SELECT语句。(属于 CRUD操作中的 Create(创建)操作)

语法:

  1. INSERT INTO table_name [(column1, column2, ...)]
  2. SELECT select_list
  3. FROM another_table
  4. [WHERE condition];

说明:

  • table_name: 你想要插入数据的表名。
  • column1, column2, …: 可选的,指定目标表中的列名。如果省略,则假定目标表中的列与SELECT语句中的列顺序和数量相匹配。
  • select_list: 从另一个表中选择的列或者表达式,它们将被插入到目标表中。
  • another_table: 数据来源的表名。
  • WHERE condition: 可选的,用于筛选源表中的记录

步骤说明:

  1. 确定目标表:首先,确定您要将数据插入到的目标表。
  2. 编写SELECT查询:编写一个SELECT查询,从源表中检索您想要插入的数据。
  3. 执行INSERT INTO … SELECT:使用INSERT INTO ... SELECT语句将SELECT查询的结果插入到目标表中。
  4. 匹配列和数据类型:确保SELECT查询返回的列与目标表中的列匹配,包括列的数量和数据类型。

在使用“插入 SELECT”操作时,要确保:

  • 目标表中的列能够接收来自源表的列数据类型。
  • 如果目标表中有不允许NULL的列,而源表的选择列表可能返回NULL值,则需要确保插入操作不会违反这些约束。
  • 如果目标表有主键或唯一键约束,确保插入的数据不会违反这些约束,除非你打算在INSERT语句中使用ON DUPLICATE KEY UPDATE子句来处理冲突。

示例:

删除表中的的重复复记录,重复的数据只能有一份

  1. -- 创建原数据表
  2. mysql> CREATE TABLE duplicate_table (id int, name varchar(20));
  3. Query OK, 0 rows affected (0.04 sec)
  4. -- 插入测试数据
  5. mysql> INSERT INTO duplicate_table VALUES
  6. -> (100, 'aaa'),
  7. -> (100, 'aaa'),
  8. -> (200, 'bbb'),
  9. -> (200, 'bbb'),
  10. -> (200, 'bbb'),
  11. -> (300, 'ccc');
  12. Query OK, 6 rows affected (0.01 sec)
  13. Records: 6 Duplicates: 0 Warnings: 0
  1. -- 创建一张空表 no_duplicate_table,结构和 duplicate_table 一样
  2. mysql> CREATE TABLE no_duplicate_table LIKE duplicate_table;
  3. Query OK, 0 rows affected (0.03 sec)
  4. -- 将 duplicate_table 的去重数据插入到 no_duplicate_table
  5. mysql> INSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table;
  6. Query OK, 3 rows affected (0.00 sec)
  7. Records: 3 Duplicates: 0 Warnings: 0
  8. -- 通过重命名表,实现原子的去重操作
  9. mysql> RENAME TABLE duplicate_table TO old_duplicate_table,
  10. -> no_duplicate_table TO duplicate_table;
  11. Query OK, 0 rows affected (0.04 sec)
  12. -- 查看最终结果
  13. mysql> SELECT * FROM duplicate_table;
  14. +------+------+
  15. | id | name |
  16. +------+------+
  17. | 100 | aaa |
  18. | 200 | bbb |
  19. | 300 | ccc |
  20. +------+------+
  21. 3 rows in set (0.00 sec)

2.6 聚合函数

注意:

  • 使用 * 做统计,不受 NULL 影响,NULL 不会计入结果

示例:

统计班级有多少同学

  1. mysql> select * from students;
  2. +----+------+-----------+--------+
  3. | id | sn | name | qq |
  4. +----+------+-----------+--------+
  5. | 1 | 1000 | 李白 | 100001 |
  6. | 2 | 1002 | 杜甫 | 123321 |
  7. | 3 | 1003 | sushi | 111111 |
  8. | 4 | 1004 | 李煜 | 234561 |
  9. | 5 | 1005 | 辛弃疾 | NULL |
  10. | 6 | 1006 | 杨慎 | NULL |
  11. +----+------+-----------+--------+
  12. 6 rows in set (0.00 sec)
  13. mysql> SELECT COUNT(*) FROM students;
  14. +----------+
  15. | COUNT(*) |
  16. +----------+
  17. | 6 |
  18. +----------+
  19. 1 row in set (0.00 sec)

2.7 group by 和 having

在select中使用group by 子句可以对指定列进行分组查询

select column1, column2, .. from table group by column;

 having和group by配合使用,对group by结果进行过滤

  1. select column1, column2, ..
  2. from table
  3. group by column
  4. having ...;

HAVING和WHERE的区别

WHERE和HAVING都是用于过滤SQL查询结果的条件子句,但它们的工作范围和作用对象不同。

WHERE子句

  • 作用范围:WHERE子句在执行SELECT语句之前应用于所有行,用于过滤原始的记录集。
  • 过滤对象:WHERE子句过滤的是未经过GROUP BY子句处理的所有行。
  • 可用的条件:WHERE子句可以包含所有的SQL条件表达式,包括比较运算符、逻辑运算符、子查询等。
  • 不适用于分组后的数据:WHERE子句在执行分组之前应用,因此它不适用于分组后的数据。

HAVING子句

  • 作用范围:HAVING子句在执行SELECT语句之前应用于所有行,但它的过滤是在GROUP BY子句处理后的分组结果上进行的。
  • 过滤对象:HAVING子句过滤的是经过GROUP BY子句处理后的分组结果。
  • 可用的条件:HAVING子句通常与聚合函数一起使用,因为它们是对分组后的结果进行操作的。HAVING子句不能包含非聚合的列,因为它们没有聚合函数。
  • 适用于分组后的数据:HAVING子句在执行分组之后应用,因此它适用于分组后的数据。

三、Update

UPDATE语句用于修改表中现有记录的列值。

语法:

  1. UPDATE table_name
  2. SET column = expr [, column = expr ...]
  3. [WHERE ...]
  4. [ORDER BY ...]
  5. [LIMIT ...]

说明:

  • UPDATE table_name: 指定要更新数据的表名。
  • SET column = expr: 指定要更新的列及其新值。可以同时更新多个列,每个列的更新用逗号隔。
  • WHERE ...:可选的,用于指定哪些行应该被更新。如果不使用WHERE子句,表中的所有行都会被更新。
  • ORDER BY ...:可选的,用于指定更新行的顺序。通常与LIMIT一起使用,以确保只更新特定的行。
  • LIMIT ...:可选的,用于限制被更新的行数。
  • SET 不支持 += 操作。

示例:

更新值为具体值:将孙悟空同学的数学成绩变更为 80 分

  1. mysql> UPDATE exam_result SET math = 80 WHERE name = '孙悟空';
  2. Query OK, 1 row affected (0.01 sec)
  3. Rows matched: 1 Changed: 1 Warnings: 0
  4. mysql> SELECT name, math FROM exam_result WHERE name = '孙悟空';
  5. +-----------+------+
  6. | name | math |
  7. +-----------+------+
  8. | 孙悟空 | 80 |
  9. +-----------+------+
  10. 1 row in set (0.00 sec)

一次更新多个列:将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分

  1. mysql> UPDATE exam_result SET math=60,chinese=70 WHERE name='曹孟德';
  2. Query OK, 1 row affected (0.00 sec)
  3. Rows matched: 1 Changed: 1 Warnings: 0
  4. mysql> SELECT name, math, chinese FROM exam_result WHERE name='曹孟德';
  5. +-----------+------+---------+
  6. | name | math | chinese |
  7. +-----------+------+---------+
  8. | 曹孟德 | 60 | 70 |
  9. +-----------+------+---------+
  10. 1 row in set (0.00 sec)

更新值为原值基础上变更:将总成绩倒数前三的 3 位同学的数学成绩加上 30 分

  1. mysql> SELECT name, math, chinese + math + english 总分 FROM exam_result
  2. -> ORDER BY 总分 LIMIT 3;
  3. +-----------+------+--------+
  4. | name | math | 总分 |
  5. +-----------+------+--------+
  6. | 宋公明 | 95 | 200 |
  7. | 刘玄德 | 115 | 215 |
  8. | 唐三藏 | 98 | 221 |
  9. +-----------+------+--------+
  10. 3 rows in set (0.00 sec)
  11. mysql> UPDATE exam_result SET math = math + 30
  12. -> ORDER BY chinese + math + english LIMIT 3;
  13. Query OK, 3 rows affected (0.01 sec)
  14. Rows matched: 3 Changed: 3 Warnings: 0
  15. mysql> SELECT name, math, chinese + math + english 总分 FROM exam_result
  16. -> WHERE name IN ('宋公明', '刘玄德', '唐三藏');
  17. +-----------+------+--------+
  18. | name | math | 总分 |
  19. +-----------+------+--------+
  20. | 唐三藏 | 128 | 251 |
  21. | 刘玄德 | 145 | 245 |
  22. | 宋公明 | 125 | 230 |
  23. +-----------+------+--------+
  24. 3 rows in set (0.00 sec)

四、Delete

4.1 delete

语法:

  1. DELETE FROM table_name
  2. [WHERE ...]
  3. [ORDER BY ...]
  4. [LIMIT ...]

注意:

  • 操作类型:DELETE是一个DML(Data Manipulation Language)操作,用于删除表中的行。
  • 删除方式:可以删除表中的部分行,通过WHERE子句指定条件来删除特定的行。
  • 性能:删除大量数据时可能会较慢,因为它会逐行删除,并且每行删除都会记录在事务日志中。
  • 触发器:会触发与删除操作相关的触发器(如果有的话)。
  • 返回信息:执行后返回被删除的行数。

示例:

删除孙悟空同学的考试成绩

  1. mysql> DELETE FROM exam_result WHERE name = '孙悟空';
  2. Query OK, 1 row affected (0.00 sec)
  3. mysql> SELECT * FROM exam_result WHERE name = '孙悟空';
  4. Empty set (0.00 sec)

删除整张表数据

  1. -- 准备测试表
  2. CREATE TABLE for_delete (
  3. id INT PRIMARY KEY AUTO_INCREMENT,
  4. name VARCHAR(20)
  5. );
  6. Query OK, 0 rows affected (0.16 sec)
  7. -- 插入测试数据
  8. INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
  9. Query OK, 3 rows affected (1.05 sec)
  10. Records: 3 Duplicates: 0 Warnings: 0
  11. -- 查看测试数据
  12. SELECT * FROM for_delete;
  13. +----+------+
  14. | id | name |
  15. +----+------+
  16. | 1 | A |
  17. | 2 | B |
  18. | 3 | C |
  19. +----+------+
  20. 3 rows in set (0.00 sec)
  21. -- 删除整表数据
  22. DELETE FROM for_delete;
  23. Query OK, 3 rows affected (0.00 sec)
  24. -- 查看删除结果
  25. SELECT * FROM for_delete;
  26. Empty set (0.00 sec)
  27. -- 再插入一条数据,自增 id 在原值上增长
  28. INSERT INTO for_delete (name) VALUES ('D');
  29. Query OK, 1 row affected (0.00 sec)
  30. -- 查看数据
  31. SELECT * FROM for_delete;
  32. +----+------+
  33. | id | name |
  34. +----+------+
  35. | 4 | D |
  36. +----+------+
  37. 1 row in set (0.00 sec)
  38. -- 查看表结构,会有 AUTO_INCREMENT=n 项
  39. SHOW CREATE TABLE for_delete\G
  40. *************************** 1. row ***************************
  41. Table: for_delete
  42. Create Table: CREATE TABLE `for_delete` (
  43. `id` int(11) NOT NULL AUTO_INCREMENT,
  44. `name` varchar(20) DEFAULT NULL,
  45. PRIMARY KEY (`id`)
  46. ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
  47. 1 row in set (0.00 sec)

4.2 truncate

语法:

TRUNCATE [TABLE] table_name

注意:

  • TABLE关键字是可省略的。
  • 操作类型:TRUNCATE是一个DDL(Data Definition Language)操作,用于删除表中的所有行。
  • 删除方式:删除表中的所有行,但不删除表结构。
  • 性能:通常比DELETE快,因为它不会逐行删除,而是直接删除数据页,并且不会记录每一行的删除操作。
  • 触发器:不会触发删除行的触发器。
  • 返回信息:执行后不返回被删除的行数

DELETE 和 TRUNCATE 的对比

  • 数据恢复:使用DELETE时,如果需要,可以通过事务回滚来恢复数据。而TRUNCATE操作通常不可逆,因为它不记录每一行的删除操作。
  • 自增字段:使用TRUNCATE后,表的自增字段(如果有的话)会被重置。而使用DELETE则不会重置 AUTO_INCREMENT项。
  • 外键约束:如果表中存在外键约束,使用DELETE可能会因为违反约束而失败,而TRUNCATE通常不会检查外键约束。
  • 触发器:如果你依赖于删除操作的触发器,那么应该使用DELETE,因为TRUNCATE不会触发这些触发器。
  • 锁:TRUNCATE通常会在表上获取更少的锁,这可能会对并发操作有影响。

示例: 

  1. -- 准备测试表
  2. CREATE TABLE for_truncate (
  3. id INT PRIMARY KEY AUTO_INCREMENT,
  4. name VARCHAR(20)
  5. );
  6. Query OK, 0 rows affected (0.16 sec)
  7. -- 插入测试数据
  8. INSERT INTO for_truncate (name) VALUES ('A'), ('B'), ('C');
  9. Query OK, 3 rows affected (1.05 sec)
  10. Records: 3 Duplicates: 0 Warnings: 0
  11. -- 查看测试数据
  12. SELECT * FROM for_truncate;
  13. +----+------+
  14. | id | name |
  15. +----+------+
  16. | 1 | A |
  17. | 2 | B |
  18. | 3 | C |
  19. +----+------+
  20. 3 rows in set (0.00 sec)
  21. -- 截断整表数据,注意影响行数是 0,所以实际上没有对数据真正操作
  22. TRUNCATE for_truncate;
  23. Query OK, 0 rows affected (0.10 sec)
  24. -- 查看删除结果
  25. SELECT * FROM for_truncate;
  26. Empty set (0.00 sec)
  27. -- 再插入一条数据,自增 id 在重新增长
  28. INSERT INTO for_truncate (name) VALUES ('D');
  29. Query OK, 1 row affected (0.00 sec)
  30. -- 查看数据
  31. SELECT * FROM for_truncate;
  32. +----+------+
  33. | id | name |
  34. +----+------+
  35. | 1 | D |
  36. +----+------+
  37. 1 row in set (0.00 sec)
  38. -- 查看表结构,会有 AUTO_INCREMENT=2 项
  39. SHOW CREATE TABLE for_truncate\G
  40. *************************** 1. row ***************************
  41. Table: for_truncate
  42. Create Table: CREATE TABLE `for_truncate` (
  43. `id` int(11) NOT NULL AUTO_INCREMENT,
  44. `name` varchar(20) DEFAULT NULL,
  45. PRIMARY KEY (`id`)
  46. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
  47. 1 row in set (0.00 sec)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/1021014
推荐阅读
相关标签
  

闽ICP备14008679号