【MySQL】7.MySQL基本查询(2)

文章目录

  • [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表:

sql 复制代码
CREATE 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');

问题示例:看似有序但不可靠

执行简单查询:

sql 复制代码
SELECT 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排序的,这可能会误导开发人员认为结果总是按主键排序。

但是,如果以后:

  1. 添加了新的索引
  2. 表进行了大量更新/删除操作
  3. 数据库进行了优化或升级
  4. 执行计划发生变化

同样的查询可能返回完全不同的顺序

复制代码
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)
相关推荐
mldlds2 小时前
MySQL加减间隔时间函数DATE_ADD和DATE_SUB的详解
android·数据库·mysql
智算菩萨4 小时前
MP3音频编码原理深度解析与Python全参数调优实战:从心理声学模型到LAME编码器精细控制
android·python·音视频
studyForMokey5 小时前
【Android面试】Activity生命周期专题
android·面试·职场和发展
chehaoman6 小时前
MySQL的索引
android·数据库·mysql
rrrjqy7 小时前
用 Docker 部署远程 MySQL:从端口踩坑到权限全开(附避坑指南)
mysql·adb·docker
ahauedu8 小时前
MySQL 8.0+ 默认使用 caching_sha2_password 插件进行密码加密
数据库·mysql
恋猫de小郭9 小时前
React Native 鸿蒙 2026 路线发布,为什么它的适配成本那么高?
android·前端·react native
_evenif9 小时前
MySql 8 一机多实例部署
linux·数据库·mysql
studyForMokey9 小时前
【Android面试】窗口机制专题
android·面试·职场和发展