MySQL3️⃣DQL 语句(❗)
Data
Query
Language(数据查询语言)查询数据库表的记录
1、SELECT
1.1、字段列表
场景:查询全部记录。
-
指定字段
SELECT 字段1, 字段2 ... FROM 表名;
-
所有字段:
*
(可读性差、效率低)SELECT * FROM 表名;
1.2、别名
场景:简化书写;多表查询时区分名称相同的字段。
AS 可省略
SELECT 字段 [AS] 别名
FROM 表名:
1.3、去重
场景:去除重复记录。
SELECT DISTINCT 字段名
FROM 表名;
1.4、函数
函数:MySQL 内置的,可直接被调用的程序代码。
通常会在 Java 代码层面实现,以减轻数据库压力。
- 聚合函数:👉 4.1
- 字符串函数
- 数值函数
- 日期函数
- 流程函数
1.4.1、字符串
功能 | |
---|---|
CONCAT(S1, ... Sn) | 拼接 |
LOWER(str) | 转小写 |
UPPER(str) | 转大写 |
LPAD(str, n, pad) | 左填充:在 str 左侧填充 n 个 pad |
RPAD(str, n, pad) | 右填充:在 str 右侧填充 n 个 pad |
TRIM(str) | 去掉头尾空格 |
SUBSTRING(str, start, len) | 子串:从 start 开始的 len 个长度 |
1.4.2、数值
功能 | |
---|---|
CEIL(x) | 向上取整 |
FLOOR(x) | 向下取整 |
MOD(x, y) | x mod y |
RAND() | 返回 [0, 1.0] 的随机浮点数 |
ROUND(x, y) | 对 x 四舍五入,保留 y 位小数 |
1.4.3、日期
功能 | |
---|---|
CURDATE() | 当前日期 |
CURTIME() | 当前时间 |
NOW() | 当前日期和时间 |
YEAR(date) | date 的年份 |
MONTH(date) | date 的月份 |
DAY(date) | date 的日期 |
DATE_ADD(date, INTERVAL exprtype) | 日期/时间值 + expr 时间间隔 |
DATEDIFF(date1,date2) | 返回 date1 和 date2 之间的天数 |
1.4.4、流程
功能 | |
---|---|
IF(value , t , f) | 若 value 为 true 则返回 t, 否则返回 f |
IFNULL(value1 , value2) | 若 value1 不为空则返回, 否则返回 value2 |
CASE WHEN [ val1 ] THEN [res1] ...ELSE[ default ] END | (多重 if)若 val1 为 true 则 返回 res1,...,否则返回默认值 default |
CASE [ expr ] WHEN [ val1 ] THEN [res1] ... ELSE [ default ] END | (switch-case)若 expr 值为 val1 则返回 res1,... ,否则返回默认值 default |
2、WHERE
格式
SELECT 字段列表
FROM 表名
WHERE 过滤条件;
2.1、比较运算符
常用运算符
- 比较:
>
、<
、>=
、<=
、=
、<=>
、!=
或<>
- 空:
IS NULL
- 闭区间:
BETWEEN ... AND ...
- 多选一:
IN(...)
- 模糊:
LIKE ...
说明
- <=>:安全等于
- 比较结果:使用比较运算符时,符合条件返回 1,否则返回 0。
- 等于比较:
- 使用
=
,当比较的元素中有 null 值时,结果会返回 null,而非预期的 0 或 1。 - 改用
<=>
可以解决该问题。
- 使用
- LIKE:模糊查询,可使用通配符
%
(任意长度)_
(单个长度)
2.2、逻辑运算符
常用运算符
- 非:
!
或NOT
- 与:
&&
或AND
- 或:
||
或OR
2.3、优先级
Hint:若无法确定优先级,可使用小括号
()
。
从高到低如下:
运算符 |
---|
! |
-(负号),~ |
^ |
*,/,% |
+,-(减号) |
<<,>> |
& |
| |
>,<,>=,<=,=(比较),<=>,!= 或 <>, IS,LIKE,REGEXP,IN |
BETWEEN,CASE,WHEN,THEN,ELSE |
NOT |
&&,AND |
XOR |
II,OR |
=(赋值),:= |
4、GROUP(分组)
4.1、聚合函数
聚合函数:将一列数据作为整体,进行纵向计算。
NULL
值不参与聚合函数运算。
-
格式:
SELECT 聚合函数(字段) FROM 表名;
-
常用聚合函数
- 统计数量:
COUNT
- 最大值:
MAX
- 最小值:
MIN
- 平均值:
AVG
- 求和:
SUM
- 统计数量:
4.2、分组查询
分组查询:按一个或多个字段分组,并计算统计结果(聚合函数)。
-
字段列表:
- SELECT:查询字段。通常为分组字段列表、聚合函数(通常起别名)。
GROUP BY
:多字段分组。后面的字段根据前面字段的分组结果进行再分组。
-
HAVING
:分组后过滤条件。-
区别 WHERE:分组前过滤,不支持对聚合函数的判断。
-
原因:分组之后才得到聚合函数的结果,在此之前无法判断聚合函数。
SELECT 字段列表 FROM 表名 [WHERE 条件] 分组 GROUP BY 分组字段列表 [HAVING 条件]
-
示例:学生
-
分组:查询各个年级的学生数量。
SELECT grade, COUNT(*) AS stu_count FROM t_student GROUP BY grade;
-
多字段分组:查询各个年级的男女生数量。
SELECT grade, gender, COUNT(*) AS stu_count FROM t_student GROUP BY grade, gender;
-
过滤条件:查询四年级的学生,平均分大于 80 的班级。
SELECT class, AVG(score) AS avg_score FROM t_student 分组前过滤 WHERE grade = 4 GROUP BY class 分组后过滤 HAVING avg_score > 80;
5、ORDER(排序)
格式
-
排序方式:ASC 升序(默认),DESC 降序。
-
多字段排序:按顺序先后排序。
SELECT 字段列表 FROM 表名 ORDER BY 字段 [排序方式];
示例:学生
-
排序:查询学生分数,从高到低进行排序。
SELECT name, score FROM t_student 降序 ORDER BY score DESC;
-
多字段排序:查询学生分数,从高到低进行排序,若分数相同则按姓名升序排序。
SELECT name, score FROM t_student 分数降序,年龄升序 ORDER BY score DESC, name [ASC];
6、LIMIT(分页)
格式
-
起始索引:
- 从 0 开始,值 =(页码 - 1)* 页面大小
- 若查询的是首页,可省略起始索引。
-
页面大小:每页显示的记录数。
SELECT 字段列表 FROM 表名 LIMIT 起始索引, 页面大小
示例:学生
-
首页:查询成绩前 10 的学生姓名及分数。
SELECT name, score FROM t_student ORDER BY score DESC 分页:可省略0 LIMIT [0,] 10;
-
一般页:查询表中第 5 页的学生记录,每页展示 10 条记录。
起始索引 = (5 - 1) * 10 = 40 SELECT * FROM t_student LIMIT 40, 10;
7、SQL 执行顺序
执行顺序
- FROM:指定查询的表,计算笛卡尔积
- ON:连接条件
- JOIN:连接类型,添加关联外部表数据
- WHERE:过滤条件(分组前)
- 流程函数
- GROUP BY:分组
- 聚合函数
- HAVING:过滤条件(分组后)
- SELECT:指定查询字段列表
- DISTINCT:指定字段去重
- UNION:合并查询结果
- ORDER BY:排序
- LIMIT:分页
Hint:虽然
HAVING
比SELECT
先执行,但支持引用SELECT
中的别名。参考 👉 MySQL 对 GROUP BY 的处理