> 文章列表 > MySQL(表的增删改查)

MySQL(表的增删改查)

MySQL(表的增删改查)

文章目录

  • 0. 前言
  • 1. Create
    • 1.1 单行数据 + 全列插入
    • 1.2 多行数据 + 指定列插入
    • 1.3 插入否则更新
    • 1.4 替换
  • 2. Retrieve
    • 2.1 SELECT 列
      • 2.1.1 全列查询
      • 2.1.2 指定列查询
      • 2.1.3 查询字段为表达式
      • 2.1.4 为查询结果指定别名
      • 2.1.5 结果去重
    • 2.2 WHERE 条件
      • 2.2.1 英语不及格的同学及英语成绩 ( < 60 )
      • 2.2.2 语文成绩在 [80, 90] 分的同学及语文成绩
      • 2.2.3 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
      • 2.2.4 姓孙的同学及孙某同学
      • 2.2.5 语文成绩好于英语成绩的同学
      • 2.2.6 总分在 200 分以下的同学
      • 2.2.7 语文成绩 > 80 并且不姓孙的同学
      • 2.2.8 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
      • 2.2.9 NULL 的查询
    • 2.3 结果排序
      • 2.3.1 同学及数学成绩,按数学成绩升序显示
      • 2.3.2 同学及 qq 号,按 qq 号排序显示
      • 2.3.3 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
      • 2.3.4 查询同学及总分,由高到低
      • 2.3.5 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示
    • 2.4 筛选分页结果
  • 3 Update
    • 3.1 将孙悟空同学的数学成绩变更为 80 分
    • 3.2 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
    • 3.3 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
    • 3.4 将所有同学的语文成绩更新为原来的 2 倍
  • 4 Delete
    • 4.1 删除数据
      • 4.1.1 删除孙悟空同学的考试成绩
      • 4.1.2 删除整张表数据
    • 4.2 截断表
  • 5 插入查询结果
  • 6. 聚合函数
    • 6.1 统计班级共有多少同学
    • 6.2 统计班级收集的 qq 号有多少
    • 6.3 统计本次考试的数学成绩分数个数
    • 6.4 统计数学成绩总分
    • 6.5 统计平均总分
    • 6.6 返回英语最高分
    • 6.7 返回>70分以上的数学最低分
  • 7. group by子句的使用

0. 前言

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

1. Create

  • 语法:
INSERT [INTO] table_name
[(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
value_list: value, [, value] ...

[]中括号里面的内容可以忽略不写。

  • 案例:
    – 创建一张学生表
mysql> create table `students`(-> id int unsigned primary key auto_increment,-> sn int not NULL unique comment '学号',-> name varchar(20) not NULL,-> qq varchar(20)-> );
Query OK, 0 rows affected (0.30 sec)

1.1 单行数据 + 全列插入

mysql> insert into `students` values(100, 1000, '唐三藏', NULL);
Query OK, 1 row affected (0.02 sec)
mysql> insert into `students` values(101, 1001, '孙悟空', '1111@qq.com');
Query OK, 1 row affected (0.04 sec)

– 查看插入结果

mysql> select * from `students`;
+-----+------+-----------+-------------+
| id  | sn   | name      | qq          |
+-----+------+-----------+-------------+
| 100 | 1000 | 唐三藏    | NULL        |
| 101 | 1001 | 孙悟空    | 1111@qq.com |
+-----+------+-----------+-------------+
2 rows in set (0.00 sec)

1.2 多行数据 + 指定列插入

mysql> insert into `students`(sn, name, qq) values-> (20001, '曹孟德', '12345@qq.com'),-> (20002, '孙忠谋', '20987@qq.com');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

– 查看插入结果

mysql> select * from `students`;
+-----+-------+-----------+--------------+
| id  | sn    | name      | qq           |
+-----+-------+-----------+--------------+
| 100 |  1000 | 唐三藏    | NULL         |
| 101 |  1001 | 孙悟空    | 1111@qq.com  |
| 102 | 20001 | 曹孟德    | 12345@qq.com |
| 103 | 20002 | 孙忠谋    | 20987@qq.com |
+-----+-------+-----------+--------------+
4 rows in set (0.00 sec)

1.3 插入否则更新

  • 由于主键或者唯一键对应的值已经存在而导致插入失败。

– 主键冲突

mysql> insert into `students`(id, sn, name) values(100, 10100, '唐大师');
ERROR 1062 (23000): Duplicate entry '100' for key 'PRIMARY'

– 唯一键冲突

mysql> insert into `students`(sn, name) values(20001, '曹操');
ERROR 1062 (23000): Duplicate entry '20001' for key 'sn'
  • 语法:
INSERT ... ON DUPLICATE KEY UPDATE
column = value [, column = value] ...
  • 案例:
mysql> insert into `students`(id, sn, name) values(100, 10100, '唐大师')-> on duplicate key update sn=10010, name='唐大师';
Query OK, 2 rows affected (0.03 sec)
0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
1 row affected: 表中没有冲突数据,数据被插入
2 row affected: 表中有冲突数据,并且数据已经被更新

– 通过 MySQL 函数获取受到影响的数据行数

mysql> select row_count();
+-------------+
| row_count() |
+-------------+
|           2 |
+-------------+
1 row in set (0.00 sec)

1.4 替换

  • 原理:
-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入。
  • 案例:
mysql> replace into `students`(sn, name) values(20001, '曹操');
Query OK, 2 rows affected (0.02 sec)

2. Retrieve

  • 语法:
SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...
  • 案例:

– 创建表结构

-- 创建表结构
mysql> CREATE TABLE exam_result (-> id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,-> name VARCHAR(20) NOT NULL COMMENT '同学姓名',-> chinese float DEFAULT 0.0 COMMENT '语文成绩',-> math float DEFAULT 0.0 COMMENT '数学成绩',-> english float DEFAULT 0.0 COMMENT '英语成绩'-> );
Query OK, 0 rows affected (0.19 sec)

– 插入测试数据

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

2.1 SELECT 列

2.1.1 全列查询

mysql> select * from `exam_result`;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |      67 |   98 |      56 |
|  2 | 孙悟空    |      87 |   78 |      77 |
|  3 | 猪悟能    |      88 |   98 |      90 |
|  4 | 曹孟德    |      82 |   84 |      67 |
|  5 | 刘玄德    |      55 |   85 |      45 |
|  6 | 孙权      |      70 |   73 |      78 |
|  7 | 宋公明    |      75 |   65 |      30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)

2.1.2 指定列查询

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

2.1.3 查询字段为表达式

– 表达式不包含字段

mysql> select id, name, 10 from `exam_result`;
+----+-----------+----+
| id | name      | 10 |
+----+-----------+----+
|  1 | 唐三藏    | 10 |
|  2 | 孙悟空    | 10 |
|  3 | 猪悟能    | 10 |
|  4 | 曹孟德    | 10 |
|  5 | 刘玄德    | 10 |
|  6 | 孙权      | 10 |
|  7 | 宋公明    | 10 |
+----+-----------+----+
7 rows in set (0.01 sec)

– 表达式包含一个字段

mysql> select id, name, english+10 from `exam_result`;
+----+-----------+------------+
| id | name      | english+10 |
+----+-----------+------------+
|  1 | 唐三藏    |         66 |
|  2 | 孙悟空    |         87 |
|  3 | 猪悟能    |        100 |
|  4 | 曹孟德    |         77 |
|  5 | 刘玄德    |         55 |
|  6 | 孙权      |         88 |
|  7 | 宋公明    |         40 |
+----+-----------+------------+
7 rows in set (0.02 sec)

– 表达式包含多个字段

mysql> select id, name, chinese+math+english from `exam_result`;
+----+-----------+----------------------+
| id | name      | chinese+math+english |
+----+-----------+----------------------+
|  1 | 唐三藏    |                  221 |
|  2 | 孙悟空    |                  242 |
|  3 | 猪悟能    |                  276 |
|  4 | 曹孟德    |                  233 |
|  5 | 刘玄德    |                  185 |
|  6 | 孙权      |                  221 |
|  7 | 宋公明    |                  170 |
+----+-----------+----------------------+
7 rows in set (0.01 sec)

2.1.4 为查询结果指定别名

  • 语法:
SELECT column [AS] alias_name [...] FROM table_name;
mysql> select id, name, chinese+math+english as `tota` from `exam_result`;
+----+-----------+------+
| id | name      | tota |
+----+-----------+------+
|  1 | 唐三藏    |  221 |
|  2 | 孙悟空    |  242 |
|  3 | 猪悟能    |  276 |
|  4 | 曹孟德    |  233 |
|  5 | 刘玄德    |  185 |
|  6 | 孙权      |  221 |
|  7 | 宋公明    |  170 |
+----+-----------+------+
7 rows in set (0.00 sec)mysql> select id, name, chinese+math+english `tota` from `exam_result`;
+----+-----------+------+
| id | name      | tota |
+----+-----------+------+
|  1 | 唐三藏    |  221 |
|  2 | 孙悟空    |  242 |
|  3 | 猪悟能    |  276 |
|  4 | 曹孟德    |  233 |
|  5 | 刘玄德    |  185 |
|  6 | 孙权      |  221 |
|  7 | 宋公明    |  170 |
+----+-----------+------+
7 rows in set (0.01 sec)

2.1.5 结果去重

mysql> select math from `exam_result`;
+------+
| math |
+------+
|   98 |
|   78 |
|   98 |
|   84 |
|   85 |
|   73 |
|   65 |
+------+
7 rows in set (0.00 sec)mysql> select distinct math from `exam_result`;
+------+
| math |
+------+
|   98 |
|   78 |
|   84 |
|   85 |
|   73 |
|   65 |
+------+
6 rows in set (0.02 sec)

2.2 WHERE 条件

  • 比较运算符:
运算符 说明
>, >=, <, <= 大于,大于等于,小于,小于等于
= 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=> 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)
!=, <> 不等于
BETWEEN a0 AND a1 范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1)
IN (option, …) 如果是 option 中的任意一个,返回 TRUE(1)
IS NULL 是 NULL
IS NOT NULL 不是 NULL
LIKE 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符
  • 逻辑运算符:
运算符 说明
AND 多个条件必须都为 TRUE(1),结果才是 TRUE(1)
OR 任意一个条件为 TRUE(1), 结果为 TRUE(1)
NOT 条件为 TRUE(1),结果为 FALSE(0)

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

mysql> select name, english from `exam_result` where english<60;
+-----------+---------+
| name      | english |
+-----------+---------+
| 唐三藏    |      56 |
| 刘玄德    |      45 |
| 宋公明    |      30 |
+-----------+---------+
3 rows in set (0.00 sec)

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

mysql> select name, chinese from `exam_result` where chinese between 80 and 90;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 孙悟空    |      87 |
| 猪悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
3 rows in set (0.00 sec)mysql> select name, chinese from `exam_result` where 80<=chinese and chinese<=90;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 孙悟空    |      87 |
| 猪悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
3 rows in set (0.00 sec)

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

mysql> select name, math from `exam_result` where math in(58, 59, 98, 99);
+-----------+------+
| name      | math |
+-----------+------+
| 唐三藏    |   98 |
| 猪悟能    |   98 |
+-----------+------+
2 rows in set (0.00 sec)mysql> select name, math from `exam_result` where math=58 or math=59 or math=98 or math=99;
+-----------+------+
| name      | math |
+-----------+------+
| 唐三藏    |   98 |
| 猪悟能    |   98 |
+-----------+------+
2 rows in set (0.00 sec)

2.2.4 姓孙的同学及孙某同学

mysql> select name from `exam_result` where name like '孙%';
+-----------+
| name      |
+-----------+
| 孙悟空    |
| 孙权      |
+-----------+
2 rows in set (0.00 sec)mysql> select name from `exam_result` where name like '孙_';
+--------+
| name   |
+--------+
| 孙权   |
+--------+
1 row in set (0.00 sec)

2.2.5 语文成绩好于英语成绩的同学

mysql> select name, chinese, english from `exam_result` where chinese>english;
+-----------+---------+---------+
| name      | chinese | english |
+-----------+---------+---------+
| 唐三藏    |      67 |      56 |
| 孙悟空    |      87 |      77 |
| 曹孟德    |      82 |      67 |
| 刘玄德    |      55 |      45 |
| 宋公明    |      75 |      30 |
+-----------+---------+---------+
5 rows in set (0.00 sec)

2.2.6 总分在 200 分以下的同学

mysql> select name, chinese+english+math  `total` from `exam_result` where chinese+englissh+math<200;
+-----------+-------+
| name      | total |
+-----------+-------+
| 刘玄德    |   185 |
| 宋公明    |   170 |
+-----------+-------+
2 rows in set (0.00 sec)

2.2.7 语文成绩 > 80 并且不姓孙的同学

mysql> select name, chinese from `exam_result` where chinese>80 and name not like '孙%';+-----------+---------+
| name      | chinese |
+-----------+---------+
| 猪悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
2 rows in set (0.00 sec)

2.2.8 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80

mysql> select *, chinese+math+english `total` from `exam_result` where (name like '孙_') or (chinese+math+english>200 and chinese<math and english>80);
+----+-----------+---------+------+---------+-------+
| id | name      | chinese | math | english | total |
+----+-----------+---------+------+---------+-------+
|  3 | 猪悟能    |      88 |   98 |      90 |   276 |
|  6 | 孙权      |      70 |   73 |      78 |   221 |
+----+-----------+---------+------+---------+-------+
2 rows in set (0.00 sec)

2.2.9 NULL 的查询

mysql> select * from `students` where qq<=>NULL;
+-----+-------+-----------+------+
| id  | sn    | name      | qq   |
+-----+-------+-----------+------+
| 100 | 10010 | 唐大师    | NULL |
| 105 | 20001 | 曹操      | NULL |
+-----+-------+-----------+------+
2 rows in set (0.00 sec)

2.3 结果排序

  • 语法:
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];

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

mysql> select name, math from `exam_result` order by math;
+-----------+------+
| name      | math |
+-----------+------+
| 宋公明    |   65 |
| 孙权      |   73 |
| 孙悟空    |   78 |
| 曹孟德    |   84 |
| 刘玄德    |   85 |
| 唐三藏    |   98 |
| 猪悟能    |   98 |
+-----------+------+
7 rows in set (0.00 sec)

2.3.2 同学及 qq 号,按 qq 号排序显示

NULL 视为比任何值都小

mysql> select name, qq from `students` order by qq asc;
+-----------+--------------+
| name      | qq           |
+-----------+--------------+
| 唐大师    | NULL         |
| 曹操      | NULL         |
| 孙悟空    | 1111@qq.com  |
| 孙忠谋    | 20987@qq.com |
+-----------+--------------+
4 rows in set (0.00 sec)

2.3.3 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示

mysql> select * from `exam_result` order by math desc, english, chinese;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |      67 |   98 |      56 |
|  3 | 猪悟能    |      88 |   98 |      90 |
|  5 | 刘玄德    |      55 |   85 |      45 |
|  4 | 曹孟德    |      82 |   84 |      67 |
|  2 | 孙悟空    |      87 |   78 |      77 |
|  6 | 孙权      |      70 |   73 |      78 |
|  7 | 宋公明    |      75 |   65 |      30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)

2.3.4 查询同学及总分,由高到低

mysql> select name, chinese+math+english `total` from `exam_result` order by `total` desc
c;
+-----------+-------+
| name      | total |
+-----------+-------+
| 猪悟能    |   276 |
| 孙悟空    |   242 |
| 曹孟德    |   233 |
| 唐三藏    |   221 |
| 孙权      |   221 |
| 刘玄德    |   185 |
| 宋公明    |   170 |
+-----------+-------+
7 rows in set (0.00 sec)

2.3.5 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示

mysql> select name, math from `exam_result` where name like '孙%' or name like '曹%' order by math desc;
+-----------+------+
| name      | math |
+-----------+------+
| 曹孟德    |   84 |
| 孙悟空    |   78 |
| 孙权      |   73 |
+-----------+------+
3 rows in set (0.00 sec)

2.4 筛选分页结果

  • 语法:
-- 起始下标为 0
--0 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;
-- 从 s 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n;
-- 从 s 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;
  • 案例:
mysql> select * from `exam_result` limit 3;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |      67 |   98 |      56 |
|  2 | 孙悟空    |      87 |   78 |      77 |
|  3 | 猪悟能    |      88 |   98 |      90 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)mysql> select * from `exam_result` limit 2, 3;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  3 | 猪悟能    |      88 |   98 |      90 |
|  4 | 曹孟德    |      82 |   84 |      67 |
|  5 | 刘玄德    |      55 |   85 |      45 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)mysql> select * from `exam_result` limit 2 offset 3;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  4 | 曹孟德    |      82 |   84 |      67 |
|  5 | 刘玄德    |      55 |   85 |      45 |
+----+-----------+---------+------+---------+
2 rows in set (0.01 sec)

3 Update

  • 语法:
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]

3.1 将孙悟空同学的数学成绩变更为 80 分

原来:

mysql> select name, math from `exam_result` where name='孙悟空';
+-----------+------+
| name      | math |
+-----------+------+
| 孙悟空    |   78 |
+-----------+------+
1 row in set (0.00 sec)

改后

mysql> update `exam_result` set math=80 where name = '孙悟空';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select name, math from `exam_result` where name='孙悟空';
+-----------+------+
| name      | math |
+-----------+------+
| 孙悟空    |   80 |
+-----------+------+
1 row in set (0.00 sec)

3.2 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分

mysql> select name, math from `exam_result` where name='曹孟德';
+-----------+------+
| name      | math |
+-----------+------+
| 曹孟德    |   84 |
+-----------+------+
1 row in set (0.00 sec)mysql> update `exam_result` set math=60, chinese=70 where name='曹孟德';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select name, math from `exam_result` where name='曹孟德';
+-----------+------+
| name      | math |
+-----------+------+
| 曹孟德    |   60 |
+-----------+------+
1 row in set (0.00 sec)

3.3 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分

mysql> update `exam_result` set math=math+30 order by chinese+english+math asc limit 3;
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3  Changed: 3  Warnings: 0
// 修改前
mysql> select *from `exam_result` order by chinese+english+math asc limit 3;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  7 | 宋公明    |      75 |   65 |      30 |
|  5 | 刘玄德    |      55 |   85 |      45 |
|  4 | 曹孟德    |      70 |   60 |      67 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)
// 修改后
mysql> select *from `exam_result` where id in(7, 5, 4);
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  4 | 曹孟德    |      70 |   90 |      67 |
|  5 | 刘玄德    |      55 |  115 |      45 |
|  7 | 宋公明    |      75 |   95 |      30 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec

3.4 将所有同学的语文成绩更新为原来的 2 倍

mysql> update `exam_result` set chinese = chinese*2 ;
Query OK, 7 rows affected (0.02 sec)
Rows matched: 7  Changed: 7  Warnings: 0
// 修改前
mysql> select *from `exam_result`;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |      67 |   98 |      56 |
|  2 | 孙悟空    |      87 |   80 |      77 |
|  3 | 猪悟能    |      88 |   98 |      90 |
|  4 | 曹孟德    |      70 |   90 |      67 |
|  5 | 刘玄德    |      55 |  115 |      45 |
|  6 | 孙权      |      70 |   73 |      78 |
|  7 | 宋公明    |      75 |   95 |      30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)
// 修改后
mysql> select *from `exam_result`;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |     134 |   98 |      56 |
|  2 | 孙悟空    |     174 |   80 |      77 |
|  3 | 猪悟能    |     176 |   98 |      90 |
|  4 | 曹孟德    |     140 |   90 |      67 |
|  5 | 刘玄德    |     110 |  115 |      45 |
|  6 | 孙权      |     140 |   73 |      78 |
|  7 | 宋公明    |     150 |   95 |      30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)

4 Delete

4.1 删除数据

  • 语法:
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]

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

mysql> delete from `exam_result` where name = '孙悟空';
Query OK, 1 row affected (0.03 sec)
mysql> select *from `exam_result`;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |     134 |   98 |      56 |
|  3 | 猪悟能    |     176 |   98 |      90 |
|  4 | 曹孟德    |     140 |   90 |      67 |
|  5 | 刘玄德    |     110 |  115 |      45 |
|  6 | 孙权      |     140 |   73 |      78 |
|  7 | 宋公明    |     150 |   95 |      30 |
+----+-----------+---------+------+---------+
6 rows in set (0.00 sec)

4.1.2 删除整张表数据

mysql> CREATE TABLE for_delete (-> id INT PRIMARY KEY AUTO_INCREMENT,-> name VARCHAR(20)-> );
Query OK, 0 rows affected (0.20 sec)mysql> INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0mysql> delete from `for_delete`;
Query OK, 3 rows affected (0.03 sec)
//  删除前
mysql> select *from `for_delete`;
+----+------+
| id | name |
+----+------+
|  1 | A    |
|  2 | B    |
|  3 | C    |
+----+------+
3 rows in set (0.00 sec)
// 删除后
mysql> select *from `for_delete`;
Empty set (0.00 sec)

4.2 截断表

  • 语法:
TRUNCATE [TABLE] table_name

注意:

  1. 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
  2. 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事
    物,所以无法回滚
  3. 会重置 AUTO_INCREMENT 项(delete不会)

5 插入查询结果

  • 语法:
INSERT INTO table_name [(column [, column ...])] SELECT ...

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

-- 创建原数据表
CREATE TABLE duplicate_table (id int, name varchar(20));
Query OK, 0 rows affected (0.01 sec)
-- 插入测试数据
INSERT INTO duplicate_table VALUES
(100, 'aaa'),
(100, 'aaa'),
(200, 'bbb'),
(200, 'bbb'),
(200, 'bbb'),
(300, 'ccc');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
  • 思路:
-- 创建一张空表 no_duplicate_table,结构和duplicate_table 一样CREATE TABLE no_duplicate_table LIKE duplicate_table;
Query OK, 0 rows affected (0.00 sec)
-- 将 duplicate_table 的去重数据插入到no_duplicate_tableINSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table;
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
-- 通过重命名表,实现原子的去重操作RENAME TABLE duplicate_table TO old_duplicate_table,
no_duplicate_table TO duplicate_table;
Query OK, 0 rows affected (0.00 sec)-- 查看最终结果
SELECT * FROM duplicate_table;
+------+------+
| id | name |
+------+------+
| 100 | aaa |
| 200 | bbb |
| 300 | ccc |
+------+------+
3 rows in set (0.00 sec)

6. 聚合函数

聚合函数对一组值执行计算并返回单一的值。

函数 说明
COUNT([DISTINCT] expr) 返回查询到的数据的数量
SUM([DISTINCT] expr) 返回查询到的数据的总和,不是数字没有意义
AVG([DISTINCT] expr) 返回查询到的数据的平均值,不是数字没有意义
MAX([DISTINCT] expr) 返回查询到的数据的最大值,不是数字没有意义
MIN([DISTINCT] expr) 返回查询到的数据的最小值,不是数字没有意义

6.1 统计班级共有多少同学

理解count机理,我们知道 select *, 1 from students; 可以保证1拼接到展示表结果的后面。
MySQL(表的增删改查)
count 就是对这一列数进行计算。

-- 使用 * 做统计,不受 NULL 影响
mysql> select count(*) from `students`;
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0.00 sec)
-- 使用表达式做统计
mysql> select count(1) from `students`;
+----------+
| count(1) |
+----------+
|        4 |
+----------+
1 row in set (0.00 sec)

6.2 统计班级收集的 qq 号有多少

注意:NULL不计入结果(NULL不参与计算)

mysql> select count(qq) from `students`;
+-----------+
| count(qq) |
+-----------+
|         2 |
+-----------+
1 row in set (0.00 sec)

6.3 统计本次考试的数学成绩分数个数

数据表
mysql> select * from `exam_result`;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |     134 |   98 |      56 |
|  3 | 猪悟能    |     176 |   98 |      90 |
|  4 | 曹孟德    |     140 |   90 |      67 |
|  5 | 刘玄德    |     110 |  115 |      45 |
|  6 | 孙权      |     140 |   73 |      78 |
|  7 | 宋公明    |     150 |   95 |      30 |
+----+-----------+---------+------+---------+
6 rows in set (0.00 sec)统计的是成绩数量
mysql> select count(math) from `exam_result`;
+-------------+
| count(math) |
+-------------+
|           6 |
+-------------+
1 row in set (0.00 sec)
统计的是去重成绩数量
mysql> select count(distinct math) from `exam_result`;
+----------------------+
| count(distinct math) |
+----------------------+
|                    5 |
+----------------------+
1 row in set (0.00 sec)

6.4 统计数学成绩总分

mysql> select sum(math) `总分` from `exam_result`;
+--------+
| 总分   |
+--------+
|    569 |
+--------+
1 row in set (0.00 sec)

6.5 统计平均总分

mysql> select avg(english+chinese+math) `平均分` from `exam_result`;
+-----------+
| 平均分    |
+-----------+
|     297.5 |
+-----------+
1 row in set (0.00 sec)

6.6 返回英语最高分

mysql> select max(english) from `exam_result`;
+--------------+
| max(english) |
+--------------+
|           90 |
+--------------+
1 row in set (0.00 sec)

6.7 返回>70分以上的数学最低分

mysql> select min(math) from `exam_result` where math>70;
+-----------+
| min(math) |
+-----------+
|        73 |
+-----------+
1 row in set (0.00 sec)// 当然还有另外写法不用聚合函数
mysql> select math from `exam_result` where math>70 order by math asc limit 1;
+------+
| math |
+------+
|   73 |
+------+
1 row in set (0.00 sec)

7. group by子句的使用

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

select column1, column2, .. from table group by column;
  • 案例:
    相关内容已经准备好了
    链接:https://gitee.com/ding-xushengyun/linux__cpp/blob/master/scott_data.sql
    • 准备工作,创建一个雇员信息表(来自oracle 9i的经典测试表)
    • emp员工表
    • dept部门表
    • salgrade工资等级表
  • 如何显示每个部门的平均工资和最高工资
mysql> select deptno, avg(sal), max(sal) from `emp` group by deptno;
+--------+-------------+----------+
| deptno | avg(sal)    | max(sal) |
+--------+-------------+----------+
|     10 | 2916.666667 |  5000.00 |
|     20 | 2175.000000 |  3000.00 |
|     30 | 1566.666667 |  2850.00 |
+--------+-------------+----------+
3 rows in set (0.00 sec)
  • 显示每个部门的每种岗位的平均工资和最低工资
mysql> select deptno, avg(sal), max(sal) from `emp` group by deptno, job;
+--------+-------------+----------+
| deptno | avg(sal)    | max(sal) |
+--------+-------------+----------+
|     10 | 1300.000000 |  1300.00 |
|     10 | 2450.000000 |  2450.00 |
|     10 | 5000.000000 |  5000.00 |
|     20 | 3000.000000 |  3000.00 |
|     20 |  950.000000 |  1100.00 |
|     20 | 2975.000000 |  2975.00 |
|     30 |  950.000000 |   950.00 |
|     30 | 2850.000000 |  2850.00 |
|     30 | 1400.000000 |  1600.00 |
+--------+-------------+----------+
9 rows in set (0.00 sec)
  • 显示平均工资低于2000的部门和它的平均工资
    • 统计各个部门的平均工资
mysql> select deptno, avg(sal) from `emp` group by deptno;
+--------+-------------+
| deptno | avg(sal)    |
+--------+-------------+
|     10 | 2916.666667 |
|     20 | 2175.000000 |
|     30 | 1566.666667 |
+--------+-------------+
3 rows in set (0.00 sec)
    • having和group by配合使用,对group by结果进行过滤
mysql> select deptno, avg(sal) `平均工资` from `emp` group by deptno having `平均工资`<2000;
+--------+--------------+
| deptno | 平均工资     |
+--------+--------------+
|     30 |  1566.666667 |
+--------+--------------+
1 row in set (0.00 sec)

小结:
SQL查询中各个关键字的执行先后顺序

from > on> join > where > group by > with > having > select > distinct > order by > limit