三、数据操作(CRUD)
- 数据库和表都创建完了,下面就是在表中添加数据记录了,那么如何在表中添加一条具体的数据记录?查看数据记录?更改数据记录?删除数据记录?本节的具体内容就是增加修改数据记录。
3.1 INSERT INTO-插入
sql
INSERT INTO table_name (第一列1, 第二列2, ...)
#列名通常可以省略不写
#每一个括号就代表一条数据具体的数据,
VALUES
(值1, 值2, ...),
(值1, 值2, 值3),
(值1, 值2, 值3),
(值1, 值2, 值3);
sql
-- 创建数据库,指定字符集和排序规则
CREATE DATABASE IF NOT EXISTS `shcool`
CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;
-- 使用数据库
USE `shcool`;
-- 创建研究生一班班级表
CREATE TABLE graduate_class_1 (
student_no VARCHAR(20) NOT NULL COMMENT '学号',
name VARCHAR(50) NOT NULL COMMENT '姓名',
gender ENUM('Male', 'Female', 'Other') NOT NULL DEFAULT 'Other' COMMENT '性别',
) COMMENT='研究生一班班级表';
3.1.1多行插入
sql
-- 多行插入三条学生信息,插入数据的信息需要类型对应
INSERT INTO graduate_class_1 VALUES('2024010', '李白', 'Female'),('2024011', '孙悟空', 'Male'),('2024012', '司马懿', 'Male');
3.1.2 单行插入
sql
INSERT INTO graduate_class_1 VALUES ('2024011', '孙悟空', 'Male');
3.1.3 指定列插入
-只插入某列,把插入的列名写出来,插入的数据对应列明即可
sql
INSERT INTO graduate_class_1 (student_no,name)
VALUES ('2024013','奶龙');
NOT NULL就是:
-这一列必须有值,不能是 NULL。它常和
DEFAULT一起用:
sql
gender ENUM('Male', 'Female', 'Other') NOT NULL DEFAULT 'Other'
- 不填时用
'Other',但永远不能填NULL。- sql语言支持隐式类型转换,Java不支持,越支持隐式转换的语言就越弱。
3.1.4 全列插入
- 把所有的列都插入数据,不用考虑上面的只插入某列。
sql
INSERT INTO graduate_class_1 VALUES('2024010', '花木兰', 'Female');
INSERT INTO graduate_class_1 VALUES('2024011', '程咬金', 'Male');
INSERT INTO graduate_class_1 VALUES('2024012', '柳杉', 'Male')
3.2 SELECT FROM-查询
3.2.1全列查询
- 其中*是通配符,代表表内所有的列
sql
SELECT * FROM graduate_class_1;
3.2.2 指定列查询
- 1.在select后⾯的查询列表中指定希望查询的列,可以是⼀列也可以是多列,中间⽤逗号隔开。
- 2.指定列的顺序与表结构中的列的顺序⽆关。
sql
#语法
SELECT 列名,列名 FROM 表名;
sql
SELECT student_no, name FROM graduate_class_1;
3.1.3 带有表达式的查询
-针对列进行简单的计算,不是对行
sql
#语法
SELECT 表达式 FROM 表名;
sql
-- 创建表结构
CREATE TABLE exam (
id BIGINT,
name VARCHAR(20) COMMENT '同学姓名',
chinese float COMMENT '语⽂成绩',
math float COMMENT '数学成绩',
english float COMMENT '英语成绩'
);
-- 插⼊测试数据
INSERT INTO exam (name, chinese, math, english) VALUES
(1, '唐三藏', 67, 98, 56),(2, '孙悟空', 87, 78, 77),
(3, '猪悟能', 88, 98, 90),(4, '曹孟德', 82, 84, 67),
(5, '刘⽞德', 55, 85, 45),(6, '孙权', 70, 73, 78);
- 把语文成绩➕10分,使用表达式查询,
sql
SELECT chinese +10 FROM exam;
- SELECT查询语句执行的一切表达式简单计算,都是临时表单,不会存储在服务器上。
- 使用表达式查询把三门成绩加起来计算总分
sql
SELECT chinese + math + english FROM exam;
3.3 AS-指定别名
3.3.1 对表达式指定别名
- 当使用表达式进行查询的时候,代码的可读性就降低了,我们可以使用 as 关键字对表达式进行重命名,提高代码的可读性。
sql
SELECT chinese + math + english as total FROM exam;
!\[cbe11869a0836392a997bd3860da7de5.png\|317]
3.3.2对表名指定别名
-此时exam 表又叫做e
sql
SELECT chinese + math + english as total FROM exam as e;
3.4 destinct-去重
- 关键字destinct,去重是行和行之间,即每条记录与每条记录之间。
- 相同的数据只显示一行。
DISTINCT只写一次,放在SELECT后面 ,它作用于后面所有列的组合,不用每一列都写。
sql
SELECT destinct 去重列1, 去重列2, .....FROM 去重表名;
3.4.1 单列去重
- 去掉这一列中的相同数据,只显示一条
| 信息 | |
|---|---|
| chinese | |
| 第一行 | 100 |
| 第二行 | 98 |
| 第三行 | 100 |
sql
SELECT destinct chinese FROM exam ;
#把语文成绩中相同的行去重只显示一行
-
上面演示分数相同,去重只显示一条记录,若多条记录比如对名字和分数都去重,则需要名字相同且分数相同才会执行去重。
-
去重结果
| 信息 | |
|---|---|
| chinese | |
| 第一行 | 100 |
| 第二行 | 98 |
3.4.2 多列去重
- 多列去重必须保证多列的数据均一致才可以进行去重。
| 数据 | 信息 | |
|---|---|---|
| name | chinese | |
| 第一行 | 唐三藏 | 100 |
| 第二行 | 孙悟空 | 100 |
| 第三行 | 唐三藏 | 100 |
sql
SELECT destinct chinese,name FROM exam ;
# 1. destinct只需要写一次就可以作用于后面的两列进行去重操作
# 2. 第一行和第二行不会执行去重操作,因为name列数据不同
# 3. 第一行和第三行才会执行去重操作
- 去重结果
| 数据 | 信息 | |
|---|---|---|
| name | chinese | |
| 第一行 | 唐三藏 | 100 |
| 第二行 | 孙悟空 | 100 |
3.5 where-条件查询
-上面学习了查询语句的语法规则,但在实际的开发场景中会有很多查询条件限制,比如价格大于多少,小于多少等等,所以添加必要的条件对查询的结果进行限制,是非常有必要的。
3.5.1 语法
sql
SELECT 列名1,列名2 FROM exam where 条件表达式;
3.5.2 常用运算符
-条件查询,查什么?从哪张表查?查询条件是什么?返回表单中返回哪些信息?
- NULL:表示在这个格子里什么数据都没有,NULL也是一个值
- NULL可以参与算数运算和比较运算,但是运算结果还是NULL
| 比较运算符 | 说明 |
|---|---|
| >, >=, <, <= | ⼤于,⼤于等于,⼩于,⼩于等于 |
| = | 判断相等,⽐如NULL = NULL ,结果还是NULL |
| <=> (常用) | 判断相等,⽐如NULL <=> NULL ,结果是TRUE |
| != | 判断不相等,为真返回TRUE |
| value BETWEEN a AND b | ==连续型左闭右开区间:[a,b)==范围匹配[a, b)。如果 a <= value < b,返回TRUE或1,NOT BETWEEN则取反 。 |
| value IN (option, ...) | ==离散型点散集合。==如果value 在optoin列表中,则返回TRUE(1),NOT IN则取反。 |
| IS NULL | 判断是否为空,为空则为真 |
| IS NOT NULL | 判断是否不为空,不为空则为真 |
| LIKE | 模糊匹配,% 表⽰任意多个(包括0个)字符;_ 表⽰任意⼀个字符,NOT LIKE则取反 |
| 逻辑运算符 | 说明 |
| AND | 多个条件必须都为 TRUE,结果为 TRUE |
| OR | 任意⼀个条件为 TRUE, 结果为 TRUE |
| NOT | 条件为 TRUE,结果为 FALSE |
3.5.3 条件查询执行过程
- 1.遍历表,取出每一行数据
- 2.把当前行带到条件表达式中进行判断是否保留
- 3.遍历完所有数据行后,按照 SELECT 指定列/表达式/别名/去重操作,对结果集合进行整合输出
- 4.order by执行排序在表达式求值之后,所以起的别名也可以在排序中使用
3.5.4 条件查询示例
3.5.4.1 查询所有英语成绩高于英语成绩的同学
sql
#比较每个同学自己的英语成绩和语文成绩进行对比。不是跨行和别的同学进行对比。
SELECT name,chinese,english FROM exam WHERE chinese > english;
3.5.4.2 是否可以使用别名进行查询?
- 查询总分在200分以下的同学
sql
SELECT name chinese,english,math FROM exam WHERE chinese + english + math < 200;
- 此处是否可以对总分起个别名,在where中使用别名进行查询?
- 不可以的,条件表达式进行比较的时候表单中并没有此别名。别名是在条件表达式执行完成之后,才出现,在表单中没有别名,起的别名也只是临时存在的。
3.5.4.3 大小于号查询
- 查询语文大于80且英语大于90分的同学
sql
SELECT name,chinese,english FROM exam WHERE chinese > 80 AND english > 90;
- 查询语文大于80或者数学大于70的同学
sql
SELECT name,chinese,math FROM exam WHERE chinese > 80 OR math > 70;
3.5.4.4 比较AND和OR的优先级
sql
SELECT name,chinese,math FROM exam WHERE chinese > 80 OR math > 70 AND english > 90;
- 比较发现AND的优先级高于OR ,上述语句是查询语文大于80或者数学大70且英语大于90。
- 优先级这东西自己手动加括号进行提升优先级即可。
3.5.4.5 使用连续区间查询
- 查询语文成绩在==[80,90)==的同学
sql
# 大小于号,结合AND
SELECT name,chinese FROM exam WHERE chinese >= 80 AND chinese < 90;
# BETWEEN AND 连续性区间来写
SELECT name,chinese FROM exam WHERE chinese BETWEEN 80 AND 90;
3.5.4.6 使用离散点查询
- 离散型点区间查询语文成绩是70,80,90分的同学
sql
SELECT name,chinese FROM exam WHERE chinese in(70,80,90);
3.5.4.7 LIKE模糊匹配查询
- LIKE模糊查询,类似于斗地主赖子模糊匹配所有牌
- % :匹配若干字符,相当于占位符,放在开头就开头占位,尾就是占位末尾字符
- _ :匹配一个字符
sql
SELECT name FROM exam WHERE name LIKE '孙%';
# 匹配所有名字以孙开头的同学
SELECT name FROM exam WHERE name LIKE '%孙';
# 匹配所有名字以孙结尾的同学
SELECT name FROM exam WHERE name LIKE '%孙%';
# 匹配所有名字包含孙字的同学
SELECT name FROM exam WHERE name LIKE '孙_';
# 匹配所有名字是两个字的:孙某
SELECT name FROM exam WHERE name LIKE '_孙';
# 匹配所有名字是两个字的:某孙
SELECT name FROM exam WHERE name LIKE '_孙_';
# 匹配所有名字是三个字的:某孙某
3.5.4.8 有关NULL注意事项
- 查询语文成绩为NULL的同学
- <=> : NUll相当于没填写数据,常用这个符号判断是否填入数据,NULL也是一个值
sql
SELECT name,chinese FROM exam WHERE chinese < = > NULL;
- 如果这个同学的语文成绩为填写,则为NUll值,chinese < = > NULL返回TRUE,会将此同学的数据行添加到结果表单,继续往后进行遍历。
| 数据 | 信息 |
|---|---|
| name | chinese |
| 张三 | NULL |
| 里斯 | NULL |
- NULL参与算数运算但会结果还是NULL
| 数据 | 查询的表单 | |
|---|---|---|
| name | chinese | math |
| 张三 | 90 | NULL |
sql
SELECT name,chinese + math FROM exam;
#math列中值是NULL,所以返回的表单中是NULL
| 数据 | 返回的表单 |
|---|---|
| name | chinese + math |
| 张三 | NULL |
3.4排序-Order by
- 根据查询顺序来看,where条件查询是在起别名等操作之前的,所以不可以使用别名进行条件限制。
- 而order by语句的执行则是在表达式/别名的操作之后的,所以可以使用别名进行排序操作。
- SELECT /ORDER BY/LIMIT等操作都是对临时表单执行的操作,不会更改硬盘上的数据。
- 硬盘上的数据永久修改是由alter table/insert/update/drop/delete等实现。
3.4.1 语法
- 排序规则:
- ASC 为升序(从⼩到⼤)
- DESC 为降序(从⼤到⼩)
- 默认为 ASC
- 当成绩这类数字数据中存在 NULL 进⾏排序时,视为⽐任何值都⼩。
sql
SELECT 列X , 列Y FROM 表名 DODER BY 列Z/表达式/别名 ASC;
#查询结果按照 **列Z/表达式/别名** 进行升序排序,结果表单仅展示 XY列 数据条目;
3.4.2 示例
- 按照列名进行升序
sql
SELECT NAME FROM EXAM DODER BY CHINESE ASC;
- 按照表达式进行升序
sql
SELECT NAME FROM EXAM DODER BY CHINESE+MATH+ENGLISH ASC;
- 按照别名进行降序
sql
SELECT NAME,CHINESE+MATH+ENGLISH as total FROM EXAM DODER BY total ASC;
3.4.3 ORDER BY 搭配WHERE
ORDER BY 排序搭配 WHERE 使用的时候放到WHERE后面
先通过WHERE筛选出来符合条件的数据条目,在进行别名/表达式等操作,最后进行排序。
- 语法
sql
SELECT 列X FROM EXAM WHERE 条件表达式 DODER BY 列Z/表达式/别名 ASC/DSC;
- 示例
sql
SELECT NAME FROM EXAM WHERE CHINESE >90 ORDER BY MATH ASC;
#筛选语文成绩大于90分的同学,并按照数学成绩进行升序排序。
3.5 limit-分页查询
3.5.1 语法
如果查询最后一页的数据树数目,没有达到limit的条数限制,也不会有任何影响,有多少条就显⽰多少条。
sql
-- 起始下标为 0
-- 从 0 开始,筛选 num 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT num;
-- 从 start 开始,筛选 num 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT start, num;
-- 从 start 开始,筛选 num 条结果,⽐第⼆种⽤法更明确,建议使⽤
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT num OFFSET start;
3.5.2 示例
- 查询语文高于80分,按照数学升序,筛选10条结果
sql
SELECT NAME FROM EXAM WHERE chinese >80 ORDER BY math ASC limit 10;
- 查询语文低于70分,按照数学降序,从第3条开始,筛选10条结果
sql
SELECT NAME FROM EXAM WHERE chinese<70 ORDER BY math DESC limit 10 OFFSET 3;
3.6 Update-修改
真正修改数据库服务器上的数据
3.6.1语法
sql
UPDATE table_name
SET 列名 = 新数据, 列名 = 新数据, 列名 = 新数据
[WHERE condition]
[ORDER BY 列Z/表达式/别名 ASC /DSC]
[LIMIT num OFFSET start]
3.6.2示例
- 把曹孟德的语文/数学成绩都改成80
sql
# 查看原始数据
select name from exam where name = '曹孟德';
# 更新数据
select name from exam SET chinese =80, math = 90 where name = '曹孟德';
#查看更新结果
select name, math, chinese from exam where name = '曹孟德';
3.7 Delete 删除
sql
#删除有一下几个常见的关键字
1.drop database javastudy1; 删除数据库
2.drop table exam; 删除表单
3.delete from table_name [WHERE where_condition]
删除数据记录,但是数据表单还在
3.7.1 语法
1.根据 WHERE/order by/limit 这些条件筛选出来哪些数据,就删除哪些数据
2.如果执⾏Delete时不加条件会删除整张表的数据。
sql
DELETE FROM table_name [WHERE where_condition] [ORDER BY ...]
[LIMIT row_count];
3.7.2 示例
sql
CREATE TABLE t_delete (
id INT,
name VARCHAR(20)
);
# 插⼊测试数据
INSERT INTO t_delete (id, name) VALUES (1, 'A'), (2, 'B'), (3, 'C');
# 查看测试表
select * from t_delete;
# 删除表中的id为1的数据
delete from t_delete WHERE id = ' 1 ';
3.8 常见的语句语法
sql
#插入数据
insert into 表名 values(值X, 值Y, 值Z);
#查询数据
select 列 from 表名 where/order by/limit num OFFSET start;
#更新数据
update 表名 set 列名 = 新的值,列名 = 新的值,列名 = 新的值 where。。。;
#删除数据
drop from 表名 where/order by/limit num OFFSET start;
3.9 insert into和select结合使用
- 就是将在表1中所查到的数据,插入到表2中去。
- select和insert into 联合起来一起使用。
- 联合使用的时候,insert into 插入的列数/对应列的数据类型 ,
要和select查询到的列数/对应列的数据类型保持一致。
3.9.1 语法
sql
INSERT INTO 表2 SELECT 列名 from 表1 where/order by/limit;
#表1和表2的 列数/对应列的数据类型 保持一致
3.9.2 示例
sql
insert into stu2 select name,chinese from stu1 where math > 90 order by math ASC limit 10 offset 1;
# 已有两张 列数/对应列的数据类型一致的学生表单 stu1/stu2。
# 先查询学生表1中数学成绩大于90分的同学,按照升序从第一个同学开始筛选十名同学
# 把筛选出来的同学的 姓名列/语文成绩列 插入到学生表2中。
3.10聚合函数
聚合函数是对一组数据进行计算,并返回单个汇总结果的函数,常见的有
COUNT()、SUM()、AVG()、MAX()和MIN()。
3.10.1 常用函数
| COUNT() | 表中一共有多少条数据 |
|---|---|
| SUM() | 求和 |
| AVG() | 平均值 |
| MAX() | 最大值 |
| MIN() | 最小值 |
3.10.2 示例
3.10.2.1COUTN
sql
#统计exam表中有多少记录
select count(*) from exam;
3.10.2.2 SUM
定义:
SUM()用于计算指定数值列的总和,NULL值不参与计算。
sql
SELECT SUM([DISTINCT] 字段名)
FROM 表名
[WHERE 条件];
sql
-- 统计所有学生的数学成绩总和
SELECT SUM(math) FROM exam;
-- 统计英语成绩总和,NULL 不参与计算
SELECT SUM(english) FROM exam;
-- 统计数学成绩大于 70 分的学生的数学总分
SELECT SUM(math) FROM exam WHERE math > 70;
注意:
SUM()主要用于数值类型的数据。SUM(DISTINCT 字段名)表示先去除重复值,再求和。NULL不参与求和;非数值字段不适合使用SUM()。
3.10.2.3 AVG
定义:
AVG()用于计算指定数值列的平均值,NULL值不参与计算。
sql
SELECT AVG(字段名) FROM 表名 [WHERE 条件];
sql
-- 计算英语成绩的平均分
SELECT AVG(english) FROM exam;
-- 计算语文、数学和英语三科总分的平均值
SELECT AVG(chinese + math + english) AS 平均总分 FROM exam;
-- 计算数学成绩大于 70 分的学生的平均分
SELECT AVG(math) FROM exam WHERE math > 70;
--执行顺序是先where筛选,在进行聚合函数
注意:
AVG()计算的是平均值,不是总和。NULL不参与平均值计算。- 当参与计算的表达式中存在
NULL时,该行表达式的结果为NULL,因此不会计入AVG()的计算。 - 一般先把NULL的数据筛选掉之后在进行聚合。
3.10.2.4 MAX
定义:
MAX()用于获取指定列或表达式中的最大值。
sql
SELECT MAX(字段名) FROM 表名 [WHERE 条件];
sql
-- 查询英语最高分
SELECT MAX(english) FROM exam;
-- 查询数学成绩大于 70 分的最高分
SELECT MAX(math) FROM exam WHERE math > 70;
注意:
- 可以用于数值、日期等可比较的数据类型。
NULL不参与最大值比较。MAX()只能返回最大值,不能直接返回取得该最大值的学生姓名。
3.10.2.5 MIN
定义:
MIN()用于获取指定列或表达式中的最小值。
sql
SELECT MIN(字段名) FROM 表名 [WHERE 条件];
sql
-- 查询英语最低分
SELECT MIN(english) FROM exam;
-- 查询数学成绩大于 70 分的最低分
SELECT MIN(math) FROM exam WHERE math > 70;
-- 同时查询数学最高分和英语最低分
SELECT MAX(math), MIN(english) FROM exam;
注意: MAX() 和 MIN() 可以在同一条查询语句中使用,也可以与 WHERE 条件配合使用。
3.11 Group by-分组查询
1.
GROUP BY:是针对某一列数据,把任意行数据相同的数据进行过滤,相同数据的行只保留一行。
3.11.1 语法
sql
SELECT 分组字段, 聚合函数(统计字段) FROM 表名
GROUP BY 分组字段
- 通常和where/having/order by搭配使用
sql
SELECT 分组字段, 聚合函数(统计字段)
FROM 表名
[WHERE 行过滤条件]
GROUP BY 分组字段
[HAVING 分组过滤条件]
[ORDER BY 排序字段];
- 执行顺序:
FROM:确定查询的数据表。WHERE:筛选参与分组的原始记录。GROUP BY:将记录划分为不同的组。HAVING:筛选分组后的结果。SELECT:返回需要显示的字段和统计结果。ORDER BY:对最终结果排序。
sql
SELECT * FROM class GROUP BY name;
--报错,这里查询的列必须是被分组的列,或者被查询的列使用聚合函数,否则报错,就是下面注意的第二点
注意:
GROUP BY可以使用多个字段进行分组。- 查询结果中,普通字段/列通常应当出现在
GROUP BY中;不在分组字段/列中的统计字段/列一般需要使用聚合函数。否则报错 - 常见的聚合函数包括
COUNT()、SUM()、AVG()、MAX()和MIN()。
3.11.2 示例
以员工表
emp为例,字段包括员工编号id、姓名name、角色role和工资salary。
- 按照
role分组,统计每个角色对应的员工人数。
sql
SELECT role, COUNT(*) AS 人数 FROM emp GROUP BY role;
- 统计每个角色的平均工资
sql
SELECT role, AVG(salary) AS 平均工资 FROM emp GROUP BY role;
- 统计每个角色的最高工资和最低工资
sql
SELECT
role,
MAX(salary) AS 最高工资,
MIN(salary) AS 最低工资
FROM emp
GROUP BY role;
- 多字段分组
sql
--按照角色和姓名的组合进行分组。
SELECT role, name, COUNT(*) AS sum
FROM emp
GROUP BY role, name;
3.11.3 having子句
定义:
HAVING用于对GROUP BY生成的分组结果进行条件过滤,常用于筛选满足统计条件的分组。
sql
--语法
SELECT 分组字段, 聚合函数(统计字段)
FROM 表名
GROUP BY 分组字段
HAVING 分组条件;
- 查询平均工资低于 1500 的角色
sql
SELECT role, AVG(salary) AS 平均工资
FROM emp
GROUP BY role
HAVING AVG(salary) < 1500;
--按照角色分组完成之后,才执行having字句,将分组结果再次进行筛选。
- 先筛选员工,再对分组结果过滤
sql
SELECT role, AVG(salary) AS 平均工资
FROM emp
WHERE salary > 500
GROUP BY role
HAVING AVG(salary) < 1500;
作用:
WHERE salary > 500:先过滤工资不超过 500 的员工。GROUP BY role:按照角色分组。HAVING AVG(salary) < 1500:再筛选平均工资低于 1500 的角色。
3.11.4 Having 与Where 的区别
最主要的区别是:执行顺序不同。
where: 分组前条件筛选,先筛选在分组
hacing :分组后条件筛选,先分组,再把分组的结果进一步筛选
3.12 内置函数
MySQL 内置函数是数据库提供的现成计算工具,可以直接用于查询、数据处理和结果格式化。
3.12.1 日期函数
日期函数用于获取当前日期和时间、提取日期部分、计算日期间隔以及对日期进行加减操作。
返回的都是数据库服务器的时间/日期
| 函数 | 作用 |
|---|---|
| CURDATE() | 返回当前日期 |
| CURTIME() | 返回当前时间 |
| NOW() | 返回当前日期和时间 |
DATE(date) |
提取日期或日期时间中的日期部分 |
ADDDATE(date, INTERVAL expr unit) |
在日期上增加指定时间 |
SUBDATE(date, INTERVAL expr unit) |
从日期中减去指定时间 |
DATEDIFF(expr1, expr2) |
计算两个日期相差的天数,即 expr1 - expr2 |
sql
-- 获取当前日期
SELECT CURDATE();
-- 获取当前时间
SELECT CURTIME();
-- 获取当前日期和时间
SELECT NOW();
-- 提取日期部分
SELECT DATE('2024-08-27 10:26:47');
-- 日期增加 31 天
SELECT ADDDATE('2024-01-02', INTERVAL 31 DAY);
-- 日期减去 1 个月
SELECT SUBDATE('2024-08-02', INTERVAL 1 MONTH);
-- 计算两个日期相差的天数
SELECT DATEDIFF('2024-12-31', '2024-12-30');
sql
3.12.2 字符串处理函数
字符串函数主要用于统计字符串长度、拼接字符串、转换大小写、截取字符串、替换内容和删除空格。
| 函数 | 作用 |
|---|---|
CHAR_LENGTH(str) |
返回字符串的字符数 |
LENGTH(str) |
返回字符串的字节数,与字符编码有关 |
CONCAT(str1, str2, ...) |
拼接多个字符串 |
CONCAT_WS(分隔符, str1, str2, ...) |
使用指定分隔符拼接字符串 |
sql
-- 查询姓名的字符数
SELECT name, CHAR_LENGTH(name) FROM exam;
-- 查询姓名的字节数
SELECT name, LENGTH(name) FROM exam;
-- 拼接姓名和成绩
SELECT CONCAT(name, '的语文成绩:', chinese, '分') FROM exam;
-- 使用逗号拼接姓名和成绩
SELECT CONCAT_WS(',', name, chinese, math, english) FROM exam;
sql
3.12.3 大小写转换函数
| 函数 | 作用 |
|---|---|
LCASE(str) / LOWER(str) |
将字符串转换为小写 |
UCASE(str) / UPPER(str) |
将字符串转换为大写 |
sql
SELECT LOWER('ABC'); -- abc
SELECT UPPER('abc'); -- ABC
3.12.4 查找与截取函数
| 函数 | 作用 |
|---|---|
INSTR(str, substr) |
返回子字符串首次出现的位置 |
LEFT(str, len) |
从左侧截取指定数量的字符 |
RIGHT(str, len) |
从右侧截取指定数量的字符 |
SUBSTR(str, pos) |
从指定位置截取到字符串末尾 |
SUBSTR(str FROM pos FOR len) |
从指定位置截取指定数量的字符 |
sql
注意: 字符串的位置索引从 `1` 开始,而不是从 `0` 开始。
-- 查找 MySQL 首次出现的位置
SELECT INSTR('Hello MySQL', 'MySQL');
-- 截取左侧 5 个字符
SELECT LEFT('Hello MySQL', 5);
-- 截取右侧 5 个字符
SELECT RIGHT('Hello MySQL', 5);
-- 从第 8 个字符开始截取
SELECT SUBSTR('Hello, MySQL', 8);
-- 从第 8 个字符开始截取 5 个字符
SELECT SUBSTR('Hello, MySQL' FROM 8 FOR 5);
3.12.5 插入与替换函数
| 函数 | 作用 |
|---|---|
INSERT(str, pos, len, newstr) |
从指定位置开始,将原字符串的一段内容替换为新字符串 |
REPLACE(str, from_str, to_str) |
将字符串中匹配的内容替换为新内容 |
HEX(str) |
返回字符串的十六进制表示;传入数字时返回其十六进制表示 |
sql
-- 在指定位置插入字符串
SELECT INSERT('Hello, Database', 8, 0, 'MySQL ');
-- 将 Database 替换为 MySQL
SELECT REPLACE('Hello Database', 'Database', 'MySQL');
-- 将字符串转换为十六进制表示
SELECT HEX('Hello MySQL');
-- 数字转换为十六进制表示
SELECT HEX(15);
3.12.6 字符串比较函数
STRCMP(expr1, expr2)用于比较两个字符串,返回值为-1、0或1,分别表示小于、相等或大于。
sql
SELECT STRCMP('text', 'text1'); -- -1
SELECT STRCMP('text', 'text'); -- 0
SELECT STRCMP('text1', 'text'); -- 1
3.12.7 删除空格与指定字符串
| 函数 | 作用 |
|---|---|
LTRIM(str) |
删除字符串左侧的空格 |
RTRIM(str) |
删除字符串右侧的空格 |
TRIM(str) |
删除字符串两侧的空格 |
sql
-- 删除左侧空格
SELECT LTRIM(' ABC');
-- 删除右侧空格
SELECT RTRIM('ABC ');
-- 删除两侧空格
SELECT TRIM(' ABC ');
3.12.8 数学函数
数学函数用于数值计算、取整、进制转换、格式化和生成随机数等操作。
| 函数 | 作用 |
|---|---|
ABS(X) |
返回绝对值 |
CEIL(X) |
向上取整,返回不小于 X 的最小整数 |
FLOOR(X) |
向下取整,返回不大于 X 的最大整数 |
CONV(数字,转换前进制, 转换后进制) |
将数字从一种进制转换为另一种进制 |
FORMAT(X, D) |
将数字格式化为带千位分隔符的字符串,并保留 D 位小 |
RAND() |
返回 [0, 1) 范围内的随机浮点数 |
ROUND(X, D) |
将数字四舍五入到小数点后 D 位 |
CRC32(expr) |
计算表达式的 CRC-32 校验值 |
sql
-- 绝对值
SELECT ABS(-3.14); -- 3.14
-- 向上取整
SELECT CEIL(20.36); -- 21
-- 向下取整
SELECT FLOOR(11.32); -- 11
-- 十进制转换为十六进制
SELECT CONV(15, 10, 16); -- F,把15从十进制转换为十六进制
-- 格式化数字,保留 2 位小数
SELECT FORMAT(1234567.654321, 2);
-- 生成随机数
SELECT RAND();
-- 四舍五入,保留 2 位小数
SELECT ROUND(3.14159, 2); -- 3.14
-- 计算字符串的 CRC-32 校验值
SELECT CRC32('Hello MySQL');
3.12.9 其他常见函数
| 函数 | 作用 |
|---|---|
VERSION() |
返回当前 MySQL 服务器版本 |
DATABASE() |
返回当前正在使用的数据库名称 |
USER() |
返回当前连接使用的用户及主机信息 |
MD5(str) |
返回字符串的 MD5 摘要,通常为 32 位十六进制字符串 |
IFNULL(val1, val2) |
如果 val1 为 NULL,返回 val2;否则返回 val1 |
sql
-- 查看 MySQL 版本
SELECT VERSION();
-- 查看当前使用的数据库
SELECT DATABASE();
-- 查看当前连接用户
SELECT USER();
-- 计算字符串的 MD5 摘要
SELECT MD5('hello world');
-- 如果第一个参数为 NULL,则返回第二个参数
SELECT IFNULL(NULL, 'MySQL');
-- 一个参数不为 NULL,直接返回第一个参数
SELECT IFNULL('database', 'MySQL');
3.12.10 筛选条件
Expression(表达式)是由常量、字段、运算符、函数等组成的计算或判断内容,可以用于
SELECT、WHERE、ORDER BY等 SQL 子句。
- 算术表达式
sql
-- 计算两数之和
SELECT 10 + 20 AS 结果;
-- 计算每个学生的三科总分
SELECT
name,
chinese + math + english AS 总分
FROM exam;
- 比较表达式
sql
-- 判断数学成绩是否大于 80
SELECT name, math
FROM exam
WHERE math > 80;
- 逻辑表达式
sql
-- 同时满足两个条件
SELECT * FROM exam WHERE chinese > 80 AND english > 80;
-- 满足任意一个条件
SELECT * FROM exam WHERE chinese > 80 OR english > 80;
-- 对条件取反
SELECT * FROM exam WHERE NOT (math > 80);