文章目录
- [6. 表的增删改查](#6. 表的增删改查)
-
- [6.2 Retrieve(读取/筛选)](#6.2 Retrieve(读取/筛选))
-
- [6.2.2 WHERE 条件](#6.2.2 WHERE 条件)
-
- [6.2.2.1 英语不及格的同学及英语成绩 ( < 60 )](#6.2.2.1 英语不及格的同学及英语成绩 ( < 60 ))
- [6.2.2.2 语文成绩在 [80, 90] 分的同学及语文成绩](#6.2.2.2 语文成绩在 [80, 90] 分的同学及语文成绩)
- [6.2.2.3 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩](#6.2.2.3 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩)
- [6.2.2.4 姓孙的同学 及 孙某同学](#6.2.2.4 姓孙的同学 及 孙某同学)
- [6.2.2.5 语文成绩好于英语成绩的同学](#6.2.2.5 语文成绩好于英语成绩的同学)
- [6.2.2.6 总分在 200 分以下的同学](#6.2.2.6 总分在 200 分以下的同学)
- [6.2.2.7 语文成绩 > 80 并且不姓孙的同学](#6.2.2.7 语文成绩 > 80 并且不姓孙的同学)
- [6.2.2.8 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80](#6.2.2.8 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80)
- [6.2.2.9 NULL 的查询](#6.2.2.9 NULL 的查询)
- [6.2.3 结果排序](#6.2.3 结果排序)
- 实例说明
-
- 问题示例:看似有序但不可靠
-
- [6.2.3.1 同学及数学成绩,按数学成绩升序显示](#6.2.3.1 同学及数学成绩,按数学成绩升序显示)
- [6.2.3.2 同学及 qq 号,按 qq 号排序显示](#6.2.3.2 同学及 qq 号,按 qq 号排序显示)
- [6.2.3.3 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示](#6.2.3.3 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示)
- [6.2.3.4 查询同学及总分,由高到低](#6.2.3.4 查询同学及总分,由高到低)
- [6.2.3.5 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示](#6.2.3.5 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示)
- [6.2.4 筛选分页结果](#6.2.4 筛选分页结果)
6. 表的增删改查
6.2 Retrieve(读取/筛选)
6.2.2 WHERE 条件
比较运算符:

逻辑运算符:

6.2.2.1 英语不及格的同学及英语成绩 ( < 60 )
mysql
-- 基本比较
mysql> SELECT name, english FROM exam_result WHERE english < 60;
+-----------+---------+
| name | english |
+-----------+---------+
| 唐三藏 | 56 |
| 刘玄德 | 45 |
| 宋公明 | 30 |
+-----------+---------+
3 rows in set (0.00 sec)
6.2.2.2 语文成绩在 [80, 90] 分的同学及语文成绩
mysql
-- 使用 AND 进行条件连接
mysql> SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese <= 90;
+-----------+---------+
| name | chinese |
+-----------+---------+
| 孙悟空 | 87 |
| 猪悟能 | 88 |
| 曹孟德 | 82 |
+-----------+---------+
3 rows in set (0.01 sec)
mysql
-- 使用 BETWEEN ... AND ... 条件
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)
6.2.2.3 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
mysql
-- 使用 OR 进行条件连接
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
-- 使用 IN 条件
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)
6.2.2.4 姓孙的同学 及 孙某同学
mysql
-- % 匹配任意多个(包括 0 个)任意字符
mysql> SELECT name FROM exam_result WHERE name LIKE '孙%';
+-----------+
| name |
+-----------+
| 孙悟空 |
| 孙权 |
+-----------+
2 rows in set (0.00 sec)
mysql
-- _ 匹配严格的一个任意字符
mysql> SELECT name FROM exam_result WHERE name LIKE '孙_';
+--------+
| name |
+--------+
| 孙权 |
+--------+
1 row in set (0.00 sec)
6.2.2.5 语文成绩好于英语成绩的同学
mysql
-- WHERE 条件中比较运算符两侧都是字段
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)
6.2.2.6 总分在 200 分以下的同学
mysql
-- WHERE 条件中使用表达式
-- 别名不能用在 WHERE 条件中
mysql> SELECT name, chinese + math + english 总分 FROM exam_result
-> WHERE chinese + math + english < 200;
+-----------+--------+
| name | 总分 |
+-----------+--------+
| 刘玄德 | 185 |
| 宋公明 | 170 |
+-----------+--------+
2 rows in set (0.00 sec)
6.2.2.7 语文成绩 > 80 并且不姓孙的同学
mysql
-- 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)
6.2.2.8 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
mysql
-- 综合性查询
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)
6.2.2.9 NULL 的查询
mysql
-- 查询 students 表
mysql> SELECT * FROM students;
+-----+-------+-----------+-------+
| id | sn | name | qq |
+-----+-------+-----------+-------+
| 100 | 10010 | 唐大师 | NULL |
| 101 | 10001 | 孙悟空 | 11111 |
| 103 | 20002 | 孙仲谋 | NULL |
| 105 | 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 的比较,= 和 <=> 的区别
# NULL = NULL 常规等于号无法判断两个未知值是否相等,返回"未知"
# NULL = 1 未知值与已知值比较,结果仍为"未知"
mysql> SELECT NULL = NULL, NULL = 1, NULL = 0;
+-------------+----------+----------+
| NULL = NULL | NULL = 1 | NULL = 0 |
+-------------+----------+----------+
| NULL | NULL | NULL |
+-------------+----------+----------+
1 row in set (0.00 sec)
# NULL <=> NULL 安全等于认为两个未知值是相等的,返回 1 (真)
# NULL <=> 1 安全等于认为未知值与已知值不相等,返回 0(假)
mysql> SELECT NULL <=> NULL, NULL <=> 1, NULL <=> 0;
+---------------+------------+------------+
| NULL <=> NULL | NULL <=> 1 | NULL <=> 0 |
+---------------+------------+------------+
| 1 | 0 | 0 |
+---------------+------------+------------+
1 row in set (0.00 sec)
6.2.3 结果排序
语法:
mysql
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...]; # column:要排序的列名、列位置或表达式
注意:没有
ORDER BY子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序。实例说明
假设我们有一个
customers表:
sqlCREATE TABLE customers ( customer_id INT AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(50), last_name VARCHAR(50), signup_date DATE ); INSERT INTO customers (first_name, last_name, signup_date) VALUES ('John', 'Smith', '2022-01-15'), ('Maria', 'Garcia', '2022-03-22'), ('Robert', 'Johnson', '2021-11-05'), ('Sarah', 'Williams', '2022-02-18'), ('David', 'Brown', '2021-12-30');问题示例:看似有序但不可靠
执行简单查询:
sqlSELECT customer_id, first_name, last_name FROM customers;第一次执行可能返回:
1, John, Smith 2, Maria, Garcia 3, Robert, Johnson 4, Sarah, Williams 5, David, Brown看起来是按照
customer_id排序的,这可能会误导开发人员认为结果总是按主键排序。但是,如果以后:
- 添加了新的索引
- 表进行了大量更新/删除操作
- 数据库进行了优化或升级
- 执行计划发生变化
同样的查询可能返回完全不同的顺序:
3, Robert, Johnson 1, John, Smith 5, David, Brown 2, Maria, Garcia 4, Sarah, Williams
6.2.3.1 同学及数学成绩,按数学成绩升序显示
mysql
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)
6.2.3.2 同学及 qq 号,按 qq 号排序显示
mysql
-- NULL 视为比任何值都小,升序出现在最上面
mysql> SELECT name, qq FROM students ORDER BY qq;
+-----------+-------+
| name | qq |
+-----------+-------+
| 唐大师 | NULL |
| 孙仲谋 | NULL |
| 曹阿瞒 | NULL |
| 孙悟空 | 11111 |
+-----------+-------+
4 rows in set (0.00 sec)
mysql
-- NULL 视为比任何值都小,降序出现在最下面
mysql> SELECT name, qq FROM students ORDER BY qq DESC;
+-----------+-------+
| name | qq |
+-----------+-------+
| 孙悟空 | 11111 |
| 唐大师 | NULL |
| 孙仲谋 | NULL |
| 曹阿瞒 | NULL |
+-----------+-------+
4 rows in set (0.00 sec)
6.2.3.3 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
mysql
-- 多字段排序,排序优先级随书写顺序
mysql> SELECT name, math, english, chinese FROM exam_result
-> ORDER BY math DESC, english, chinese;
+-----------+------+---------+---------+
| name | math | english | chinese |
+-----------+------+---------+---------+
| 唐三藏 | 98 | 56 | 67 |
| 猪悟能 | 98 | 90 | 88 |
| 刘玄德 | 85 | 45 | 55 |
| 曹孟德 | 84 | 67 | 82 |
| 孙悟空 | 78 | 77 | 87 |
| 孙权 | 73 | 78 | 70 |
| 宋公明 | 65 | 30 | 75 |
+-----------+------+---------+---------+
7 rows in set (0.00 sec)
6.2.3.4 查询同学及总分,由高到低
mysql
-- ORDER BY 中可以使用表达式
mysql> SELECT name, chinese + english + math FROM exam_result
-> ORDER BY chinese + english + math DESC;
+-----------+--------------------------+
| name | chinese + english + math |
+-----------+--------------------------+
| 猪悟能 | 276 |
| 孙悟空 | 242 |
| 曹孟德 | 233 |
| 唐三藏 | 221 |
| 孙权 | 221 |
| 刘玄德 | 185 |
| 宋公明 | 170 |
+-----------+--------------------------+
7 rows in set (0.00 sec)
mysql
-- ORDER BY 子句中可以使用列别名
mysql> SELECT name, chinese + english + math 总分 FROM exam_result
-> ORDER BY 总分 DESC;
+-----------+--------+
| name | 总分 |
+-----------+--------+
| 猪悟能 | 276 |
| 孙悟空 | 242 |
| 曹孟德 | 233 |
| 唐三藏 | 221 |
| 孙权 | 221 |
| 刘玄德 | 185 |
| 宋公明 | 170 |
+-----------+--------+
7 rows in set (0.00 sec)
6.2.3.5 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示
mysql
-- 结合 WHERE 子句 和 ORDER BY 子句
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)
6.2.4 筛选分页结果
语法:
mysql
-- 起始下标为 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,避免因为表中数据过大,查询全表数据导致数据库卡死按
id进行分页,每页3条记录,分别显示 第1、2、3页
mysql
-- 第 1 页
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.01 sec)
mysql
-- 第 2 页
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
-- 第 3 页
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)