MySQL快速入门——基本查询(上)
MySQL快速入门——基本查询(上)
- 1. Create(创建)
- 1.1 单行数据 + 全列插入
- 1.2 多行数据 + 指定列插入
- 1.3 插入否则更新 on duplicate key
- 1.4 替换 replace
- 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 结果排序 order by
- 2.3.1 同学及数学成绩,按数学成绩升序显示
- 2.3.2 同学及 qq 号,按 qq 号排序显示
- 2.3.3 查询同学各门成绩,依次按 数学降序,英语降序,语文升序的方式显示
- 2.3.4 查询同学及总分,由高到低(重点)
- 2.3.5 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示
- 2.4 筛选分页结果
CRUD:Create(创建),Retrieve(读取),Update(更新),Delete(删除)
1. Create(创建)
1. 语法
values就像一个扁担,左边的列和右边的值一一对应。
INSERT [INTO] table_name[(column [, column] ...)]VALUES (value_list) [, (value_list)] ...value_list: value, [, value] ...
2. 案例
-- 创建一张学生表
CREATE TABLE students (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,sn INT NOT NULL UNIQUE COMMENT '学号',name VARCHAR(20) NOT NULL,qq VARCHAR(20)
);
1.1 单行数据 + 全列插入
全列插入指的是 values 左边没有内容,右边就必须把全部的列信息带上,才能正确插入。
-- 插入两条记录,value_list 数量必须和定义表的列的数量及顺序一致
mysql> INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
Query OK, 1 row affected (0.01 sec)mysql> INSERT INTO students VALUES (101, 10001, '孙悟空', '11111');
Query OK, 1 row affected (0.01 sec)mysql> SELECT * FROM students;
+-----+-------+-----------+-------+
| id | sn | name | qq |
+-----+-------+-----------+-------+
| 100 | 10000 | 唐三藏 | NULL |
| 101 | 10001 | 孙悟空 | 11111 |
+-----+-------+-----------+-------+
2 rows in set (0.00 sec)
1.2 多行数据 + 指定列插入
-- 插入两条记录,value_list 数量必须和指定列数量及顺序一致
mysql> insert into students (id, sn, name) values
-> (102, 20001, '曹孟德'),
-> (103, 20002, '孙仲谋');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0mysql> select * from students;
+-----+--------+-----------+-------+
| id | sn | name | qq |
+-----+--------+-----------+-------+
| 100 | 10000 | 唐三藏 | NULL |
| 101 | 10001 | 孙悟空 | 11111 |
| 102 | 20001 | 曹孟德 | NULL |
| 103 | 20002 | 孙仲谋 | NULL |
+-----+--------+-----------+-------+
4 rows in set (0.00 sec)
1.3 插入否则更新 on duplicate key
由于 主键 或者 唯一键 对应的值已经存在而导致插入失败:
-- 主键冲突
mysql> INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大师');
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 UPDATEcolumn = value [, column = value] ...
mysql> INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大师')-> ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大师';
Query OK, 2 rows affected (0.01 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)-- ON DUPLICATE KEY 当发生重复key的时候
1.4 替换 replace
一般 replace 使用较多,比 on duplicate 常用。毕竟明眼人都能看出来 replace 使用的字数更少。
-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入
mysql> REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞒');
Query OK, 2 rows affected (0.00 sec)
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入
2. Retrieve(读取)
2.1 select 列
1. 语法:
SELECT[DISTINCT] {* | {column [, column] ...}[FROM table_name][WHERE ...][ORDER BY column [ASC | DESC], ...]LIMIT ...
2. 案例
-- 创建表结构
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 '英语成绩'
);-- 插入测试数据
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.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
2.1.1 全列查询
-- 通常情况下不建议使用 * 进行全列查询
-- 1. 查询的列越多,意味着需要传输的数据量越大;
-- 2. 可能会影响到索引的使用。(索引待后面课程讲解)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.00 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.00 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.00 sec)
2.1.4 为查询结果指定别名
1. 语法
SELECT column [AS] alias_name [...] FROM table_name;
2. 案例
mysql> SELECT id, name, chinese + math + english 总分 FROM exam_result;
+----+-----------+--------+
| id | name | 总分 |
+----+-----------+--------+
| 1 | 唐三藏 | 221 |
| 2 | 孙悟空 | 242 |
| 3 | 猪悟能 | 276 |
| 4 | 曹孟德 | 233 |
| 5 | 刘玄德 | 185 |
| 6 | 孙权 | 221 |
| 7 | 宋公明 | 170 |
+----+-----------+--------+
7 rows in set (0.00 sec)
2.1.5 结果去重
-- 98 分重复了
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.01 sec)
2.2 where 条件
1. 比较运算符:
| 运算符 | 说明 |
|---|---|
| >, >=, <, <= | 大于,大于等于,小于,小于等于 |
| = | 等于,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 个)任意字符;_ 表示任意一个字符 |
2. 逻辑运算符:
| 运算符 | 说明 |
|---|---|
| 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 chinese >= 80 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 = 58-> or math = 59-> or math = 98-> or math = 99;
+-----------+------+
| name | math |
+-----------+------+
| 唐三藏 | 98 |
| 猪悟能 | 98 |
+-----------+------+
2 rows in set (0.00 sec)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)
2.2.4 姓孙的同学 及 孙某同学
%匹配任意多个(包括 0 个)任意字符;_匹配严格的一个任意字符。
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, math+chinese+english total from exam_result where math+chinese+english < 200;
+-----------+-------+
| name | total |
+-----------+-------+
| 刘玄德 | 185 |
| 宋公明 | 170 |
+-----------+-------+
2 rows in set (0.00 sec)
- 这里要特别注意,
where后如果直接写total会报错:
mysql> select name, math+chinese+english total from exam_result where total < 200;
ERROR 1054 (42S22): Unknown column 'total' in 'where clause'
- 这是由于
sql语句的执行顺序导致的:

- 就像企业去校招一样,先选择去哪个学校(
from exam_result)。HR到了学校之后,一定是拿着招聘要求去筛选人(where ...)。最后才去查看所有学生的数据,到底有哪些符合要求(math+chinese+english total)。 - 由此可见,当
where语句执行时,total还没有被计算出来,所以肯定会报错。 - 有聪明的同学灵机一动,想到这样写行不行呢:
select name, total from exam_result where math+chinese+english total < 200;。答案是不行的,语法上错误。 - 所以想要筛选总分,只有上述一种写法,要牢记。
2.2.7 语文成绩 > 80 并且不姓孙的同学
-- AND 与 NOT 的使用
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 name, chinese, math, english, chinese + math + english 总分 FROM exam_result -> WHERE name LIKE '孙_' OR -> ( chinese + math + english > 200 AND chinese < math AND english > 80 );
+-----------+---------+------+---------+--------+
| name | chinese | math | english | 总分 |
+-----------+---------+------+---------+--------+
| 猪悟能 | 88 | 98 | 90 | 276 |
| 孙权 | 70 | 73 | 78 | 221 |
+-----------+---------+------+---------+--------+
2 rows in set (0.00 sec)
2.2.9 NULL 的查询
-- 查询 students 表
+-----+-------+-----------+-------+
| id | sn | name | qq |
+-----+-------+-----------+-------+
| 100 | 10010 | 唐大师 | NULL |
| 101 | 10001 | 孙悟空 | 11111 |
| 103 | 20002 | 孙仲谋 | NULL |
| 104 | 20001 | 曹阿瞒 | NULL |
+-----+-------+-----------+-------+
4 rows in set (0.00 sec)-- 查询 qq 号已知的同学姓名
mysql> SELECT name, qq FROM students WHERE qq IS NOT NULL;
+-----------+-------+
| name | qq |
+-----------+-------+
| 孙悟空 | 11111 |
+-----------+-------+
1 row in set (0.00 sec)-- NULL 和 NULL 的比较,= 和 <=> 的区别
mysql> SELECT NULL = NULL, NULL = 1, NULL = 0;
+-------------+----------+----------+
| NULL = NULL | NULL = 1 | NULL = 0 |
+-------------+----------+----------+
| NULL | NULL | NULL |
+-------------+----------+----------+
1 row in set (0.00 sec)mysql> SELECT NULL <=> NULL, NULL <=> 1, NULL <=> 0;
+---------------+------------+------------+
| NULL <=> NULL | NULL <=> 1 | NULL <=> 0 |
+---------------+------------+------------+
| 1 | 0 | 0 |
+---------------+------------+------------+
1 row in set (0.00 sec)
2.3 结果排序 order by
1. 语法:
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASCSELECT ... FROM table_name [WHERE ...]ORDER BY column [ASC|DESC], [...];
注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序。
2.3.1 同学及数学成绩,按数学成绩升序显示
mysql> SELECT name, math FROM exam_result ORDER BY math asc;
+-----------+------+
| 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;
+-----------+-------+
| name | qq |
+-----------+-------+
| 唐大师 | NULL |
| 孙仲谋 | NULL |
| 曹阿瞒 | NULL |
| 孙悟空 | 11111 |
+-----------+-------+
4 rows in set (0.00 sec)
2.3.3 查询同学各门成绩,依次按 数学降序,英语降序,语文升序的方式显示
-- 多字段排序,排序优先级随书写顺序
mysql> SELECT name, math, english, chinese FROM exam_result -> order by math desc, english desc, chinese asc;
+-----------+------+---------+---------+
| name | math | english | chinese |
+-----------+------+---------+---------+
| 猪悟能 | 98 | 90 | 88 |
| 唐三藏 | 98 | 56 | 67 |
| 刘玄德 | 85 | 45 | 55 |
| 曹孟德 | 84 | 67 | 82 |
| 孙悟空 | 78 | 77 | 87 |
| 孙权 | 73 | 78 | 70 |
| 宋公明 | 65 | 30 | 75 |
+-----------+------+---------+---------+
7 rows in set (0.00 sec)
2.3.4 查询同学及总分,由高到低(重点)
-- ORDER BY 子句中可以使用列别名mysql> select name, chinese+math+english total from exam_result-> order by total desc;
+-----------+-------+
| name | total |
+-----------+-------+
| 猪悟能 | 276 |
| 孙悟空 | 242 |
| 曹孟德 | 233 |
| 唐三藏 | 221 |
| 孙权 | 221 |
| 刘玄德 | 185 |
| 宋公明 | 170 |
+-----------+-------+
7 rows in set (0.00 sec)
- 这里为什么又可以使用别名了?还是要说
sql的执行顺序:

order是对结果进行排序,那么首先肯定要有结果,这个结果通过筛选加计算后,才算真正产生。所以当运行到order by total时,total已经被计算了。
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 筛选分页结果
1. 语法:
-- 起始下标为 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;
建议:对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死
2. 案例
- 按
id进行分页,每页 3 条记录,分别显示 第 1、2、3 页:
mysql> SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3 OFFSET 0;
+----+-----------+------+---------+---------+
| id | name | math | english | chinese |
+----+-----------+------+---------+---------+
| 1 | 唐三藏 | 98 | 56 | 67 |
| 2 | 孙悟空 | 78 | 77 | 87 |
| 3 | 猪悟能 | 98 | 90 | 88 |
+----+-----------+------+---------+---------+
3 rows in set (0.00 sec)mysql> SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3 OFFSET 3;
+----+-----------+------+---------+---------+
| id | name | math | english | chinese |
+----+-----------+------+---------+---------+
| 4 | 曹孟德 | 84 | 67 | 82 |
| 5 | 刘玄德 | 85 | 45 | 55 |
| 6 | 孙权 | 73 | 78 | 70 |
+----+-----------+------+---------+---------+
3 rows in set (0.00 sec)mysql> SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3 OFFSET 6;
+----+-----------+------+---------+---------+
| id | name | math | english | chinese |
+----+-----------+------+---------+---------+
| 7 | 宋公明 | 65 | 30 | 75 |
+----+-----------+------+---------+---------+
1 row in set (0.00 sec)
