MySQL —— SQL 语句总结

MySQL 简介及SQL 语句 二、部署 MySQL 数据库2.优化调整 MySQL 程序3.初始化 MySQL 数据库服务4.登录验证三、SQL 语句操作——增删改查2.数据记录类型3.表相关 SQL4.简单操作一、数据库概述==========================================================================数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作。1.数据库的分类关系型数据库: 阅读详情

在这里插入图片描述


阅读原文


前言

这是关于 MySQL 系列文章的第二篇,在上一篇 《MySQL —— 数据库基础》 中,主要介绍了一些数据库的基础概念、创建表的方式以及使用 DDL 数据定义语言对表的操作,本篇的主要内容是在开发中使用 SQL 语句对数据库的增、删、改、查,函数、聚合函数的应用以及表连接,本篇大部分内容都贴近开发中的实际操作,不会像上一篇那么枯燥,也可当作一个小小的查询文档,还有一句话不得不再次赘述,数据库博大精深,本系列文章内容较浅,适合于前端的同学们对 MySQL 的入门,这也是我的学习笔记,希望可以帮助大家。


准备数据

还记得在上一篇的最后我们使用 DDL 创建了完整的表关系,student、score 和 course 三张表如下图。

在这里插入图片描述

其中 score 是外键表,创建外键约束关联了两张主键表 scudent 和 cource,接下来的 SQL 语句都是基于这几张表来进行的。


SQL 的组成

1、DDL

DDL(data definition language)是数据定义语言,主要命令有 CREATE、ALTER、DROP 等,DDL 主要用在定义或改变数据表(TABLE)的结构、数据类型、表之间的链接和约束等初始化工作上,大多数在建立表时使用,在上一篇中 DDL 操作表的部分着重做了介绍并创建数据表,也可以将存储 DDL 语句的文件存储在 .sql 后缀名结尾的文件当中,在 DBMS 数据管理系统中导入,直接创建数据库。

2、DML

DML(data manipulation language)是数据操做语言,通过 DML 语句对数据库数据表中的实体进行增、删、改、查,数据量非常大时,我们不可能使用 DBMS 一条一条的操作数据,所以都是通过代码完成操作,DML 是在学习 MySQL 数据库中最最重要的内容,也是本篇的重点,后面会非常详细的说明。

3、DCL

DCL(data control language)是数据库控制语言,用来设置或更改数据库用户或角色权限的语句,包括 grant、revoke 等,grant 是授权命令,revoke 是收回权限命令。


SQL 运算符

SQL 元算符分为算术运算符、逻辑运算符和比较运算符,是用来完成列之间或者变量之间的比较和运算的。

1、算术运算符

运算符说明
+加运算,求两个数或表达式相加的和,如 1 + 1
-减运算,求两个数或表达式相减的差,如 4 - 1
*乘运算,求两个数或表达式相乘的积,如 2 * 2
\除运算,求两个数或表达式相除的商,如 6 / 4
%取模运算,求两个数或表达式相除的余数,如 6 % 4

2、逻辑运算符

运算符说明
AND当且仅当两个布尔表达式都为 true 时,返回 true
OR当且仅当两个布尔表达式都为 false 时,返回 false
NOT布尔表达式的值取反

3、比较运算符

运算符说明
=等于
>大于
<小于
>=大于等于
<=小于等于
<>不等于
!=不等于
<=>安全不等于

SQL 语句之数据增、删、改

1、插入数据行

语法:

INSERT [INTO] 表名 [(列名)] VALUES (值列表)

给上面的 student 表插入一条数据,姓名为张三,卡号为 100,年龄为 20,城市默认为北京。

INSERT INTO `student` (`name`, `idcard`, `age`, `city`)
VALUES ("张三", "100", 20, NULL);

注意事项:

  • 每次插入一行数据,不能只插入一部分数据,即不能只插入了一个实体的某几列,插入的数据是否有效将严格按照实体的完整性要求来检验;
  • 每个数据值的数据类型、精度、位数必须要与对应的列名精确匹配,严格按照域的完整性要求来检验;
  • 不能为标识符指定值(规定),例如作为主键自增的标识列;
  • 如果某字段设置非空约束,则该列必须插入不为 null 的数据;
  • 插入数据时还要符合检查性约束的要求,如非空约束、唯一约束等;
  • 设置了默认值的列,有缺省值时,可以使用 DEFAULT 关键字来代替插入的实际值。

2、更新数据行

语法:

UPDATE 表名 SET 列名 = 更新值 [WHERE <更新条件>]

将 student 表中 id 为 1 的实体的 idcard 列值改为 200,age 列值改为 24。

UPDATE `student`
SET `idcard` = "200", `age` = 24
WHERE `id` = 1 AND `name` = "张三";

将 student 表中 city 列为空的实体 city 列的值设置为 “上海”。

UPDATE `student`
SET `city` = "上海"
WHERE `city` IS NULL;

注意事项:

  • 更新多列时,列赋值语句之间使用逗号分隔,一定要加更新条件,否则会更新所有的行;
  • 多个联合条件根据逻辑关系使用 AND 或 OR 连接。

3、删除数据行

语法:

DELETE [FROM] 表名 [WHERE <删除条件>]

删除 student 表中 age 列值为 24 或者 idcard 列值为 200 的实体。

DELETE FROM `student`
WHERE `age` = 24 OR `idcard` = 200;

注意事项:

  • 删除的是一整行的数据,所以不需要提供列名;
  • 如果要删除主表数据,则要先删除外键连接对应的子表数据。

SQL 语句之数据查询

在 SQL 语句的增、删、改、查中,最繁琐和复杂的就是查询语句,在实际开发中七分查询三分增、删、改的说法一点也不为过,查询语句是在业务中使用最多的语句,所以我们将查询语句与增、删、改分离出来,用这单独的一节来叙述。

1、查询简介

查询就是从客户端发出查询,请求数据库服务器,并从数据库返回查询结果的过程,每次执行查询只是从数据表中提取数据,并按照表的方式呈现出来,查询产生的虚拟表并不会保存。

2、查询语法

SELECT <列名>
FROM <表名>
[WHERE <查询条件表达式>]
[ORDER BY <排序的列名> [ASC 或 DESC]]
LIMIT <起始索引>, <查询条数>;

我们继续操作之前的三张表,查询 “北京” 的学生并按 id 的正序排序。

SELECT *
FROM `student`
WHERE `city` = "北京"
ORDER BY `id` ASC;

上面 SQL 语句中的 * 代表查询表中所有的列,如果查找某些列,列名之间用 , 分隔。

3、别名

在查询数据表的某个列的时候可以通过别名改变查询到虚拟表列的名称,在列的后面使用 AS 关键字加上别名,AS 可以省略。

SELECT `name`, `age`, `city` AS `城市`
FROM `student`
WHERE `city` = "北京"
ORDER BY `id` DESC;

4、查询空行

假设表中的某一列值为 null,我们可以通过 IS 关键字查询这一列值为空的数据。

SELECT `name`, `age`, `city`
FROM `student`
WHERE `city` IS NULL
ORDER BY `id` DESC;

5、常量列

查询一个数据表中没有的列,我们可以在查询时将这一列增加为常量列,如 city 的值都是中国的,我们可以增加一个常量列值都为 “中国”,列名为 country。

SELECT `name`, `age`, `city`, "中国" AS `country`
FROM `student`;

6、查询列的不重复数据

假设查询 student 表中同学们来自那些城市,正常按照 city 列查询,有多个条数据的 city 列都来自同一个城市,我们可以使用 DISTINCT 关键字,只保留一个。

SELECT DISTINCT `city`
FROM `student`;

7、限制查询条数

LIMIT 关键字用来限制查询返回的条数,后面的值为数字,下面查询 student 表,只返回 3 条数据。

SELECT *
FROM `student`
LIMIT 3;

当 LIMIT 参数大于一个时,第一个参数代表起始的索引(跳过的条数),第二个参数代表返回的条数,中间用 , 隔开,还是查询 student 表,返回第 4 到 6 条数据。

SELECT *
FROM `student`
LIMIT 3, 3;

8、运算符在查询中的使用

SELECT 1 + 1; -- 2
SELECT 1 + "1"; -- 2
SELECT 1 + "panda"; -- 1
SELECT 1 + NULL; -- NULL

通过上面的例子可以看出在 SQL 语句中,使用算术运算符相加无法起到字符串拼接的作用,会将值转化为数字进行计算,字符串转为数字 0,数字与 null 相加结果为 null,没意义。

9、查询语句练习案例

首先我们将上面的三张表 student,cource 和 score 三张表插入数据。

-- 给 student 表插入数据
INSERT INTO `student`
VALUES ("1", "郭靖", "1", "40", "济南", "山东省", "1978-09-03", 1, "1@qq.com");
INSERT INTO `student`
VALUES ("2", "黄蓉", "2", "36", "济南", "山东省", "1982-09-03", 0, "2@qq.com");
INSERT INTO `student`
VALUES ("3", "杨过", "3", "22", "终南山", "陕西省", "1996-09-03", 1, "3@qq.com");
INSERT INTO `student`
VALUES ("4", "小龙女", "4", "28", "终南山", "陕西省", "1990-09-03", 0, "4@qq.com");
INSERT INTO `student`
VALUES ("5", "欧阳锋", "5", "70", "白驼山", "新疆", "1948-09-03", 1, "5@qq.com");

-- 给 cource 表插入数据
INSERT INTO `course` VALUES ("1", "语文");
INSERT INTO `course` VALUES ("2", "数学");
INSERT INTO `course` VALUES ("3", "英语");

-- 给 score 表插入数据
INSERT INTO `score` VALUES ("1", "1", "100");
INSERT INTO `score` VALUES ("1", "2", "90");
INSERT INTO `score` VALUES ("1", "3", "70");
INSERT INTO `score` VALUES ("2", "1", "100");
INSERT INTO `score` VALUES ("2", "2", "40");
INSERT INTO `score` VALUES ("2", "3", "80");
INSERT INTO `score` VALUES ("3", "1", "100");
INSERT INTO `score` VALUES ("3", "2", "60");
INSERT INTO `score` VALUES ("3", "3", "80");

添加数据后的三张表如下图:

在这里插入图片描述

查询山东省学生的全部信息:

SELECT *
FROM `student`
WHERE `province` = "山东";

查询山东省男学生的全部信息:

SELECT *
FROM `student`
WHERE `province` = "山东" AND `gender` = 1;

查询没填写电子邮箱学生的姓名和身份证号:

SELECT `name`, `idcard`
FROM `student`
WHERE `email` IS NULL;

把学生的成绩按升序排列:

SELECT *
FROM `score`
ORDER BY `grade` ASC;

课程编号升序排列,成绩降序排列:

SELECT *
FROM `score`
ORDER BY `course_id` ASC, `grade` DESC;

SQL 语句之模糊查询

在上一节中我们所使用的查询叫 “完整查询” 或 “精准查询”,而本节的 “模糊查询” 是指查询条件不明确,可以尽量多的匹配满足查询条件的数据。

1、通配符

“通配符” 用于代替一个或多个真正的字符,与 LIKE 关键字一起使用,通配符的解释、示例如下表。

通配符解释示例符合条件的值
_一个任意字符LIKE "a_"as、ad 等
%任意长度的字符串LIKE "c%"code、cat 等
[ ]括号中所指定范围内的一个字符LIKE "1[35]5"135 或 155
[^]不再括号中所指定范围内的一个字符LIKE "1[^1-2]5"135 或 155 等

查询 student 表中 email 列是 qq 邮箱的学生信息。

SELECT *
FROM `student`
WHERE `emai` LIKE `%qq%`;

查询 student 表中姓杨的名字为两个字的所有学生信息。

SELECT * FROM `student`
WHERE `name` LIKE "杨_";

2、BETWEEN…AND…

BETWEEN...AND... 用于查询某一列在指定范围内的记录,包括两个边界。

查询 score 表中成绩在 80 到 90 范围内的所有学生信息。

-- 精准查询
SELECT *
FROM `score`
WHERE `grade` >= 80 AND `grade` <= 90;

-- 模糊查询
SELECT *
FROM `score`
WHERE `grade` BETWEEN 80 AND 90;

3、IN

查询某一列中的值在列出的内容列表中。

查询 student 表中 city 列为 “北京” 或 “上海” 或 “杭州” 所有学生的信息。

-- 精准查询
SELECT *
FROM `student`
WHERE `city` = "北京" OR `city` = "上海" OR `city` = "杭州";

-- 模糊查询
SELECT *
FROM `student`
WHERE `city` IN ("北京", "上海", "杭州");

截断表

作为主键的标识列,值是会随着数据的增加,自动递增的,且具有 “断号保留” 的特性,随着表中数据的增删,标识列的值会非常混乱,我们可以通过截断表来解决该问题,截断表有两个作用如下。

  • 使表中数据的标识列的值重新从 1 开始计数;
  • 清空表中数据;

使用截断表时,表的列和约束不会改动,使用的前提是表与表之间不能存在外键约束,表之间如果通过外键进行关联,无法清空主表中数据,即无法截断表。

语法:

TRUNCATE TABLE 表名

截断 student 表:

TRUNCATE TABLE `student`;

截断表操作轻易不要使用,因为普通的 SQL 操作会记录日志,并且可以还原,而 TRUNCATE 操作不会记录日志,并且不可还原,万一删错,彻底完蛋。


函数

在 MySQL 中有很多内置的函数帮我们实现一些功能,函数大类可分为普通函数和聚合函数,我们本节主要介绍普通函数,常用的普通函数大概可分为字符函数、数字函数、日期函数和流程控制函数等,还有一些与数据库相关的辅助函数以及自定义函数,都会在本节一一介绍。

1、字符函数

(1) LENGTH

LENGTH 函数的作用是返回输入字符串的长度。

SELECT LENGTH("panda"); -- 5
SELECT LENGTH("你好啊"); -- 9
(2) CONCAT 和 CONCAT_WS

CONCAT 函数用于将多个字符串拼接成一个字符串,CONCAT_WS 函数用于使用分隔符将多个字符串拼接成一个字符串,第一个参数为分隔符。

SELECT CONCAT("Panda", "Shen"); -- PandaShen
SELECT CONCAT_WS("-", "Hello", "Panda", "Shen"); -- Hello-Panda-Shen
(3) UPPER 和 LOWER

UPPER 函数用于将字符串转换为大写,LOWER 函数用于将字符串转换为小写。

SELECT UPPER("panda"); -- PANDA
SELECT LOWER("PANDA"); -- panda
(4) SUBSTR

SUBSTR 函数用于截取字符串,第一个参数为源字符串,第二个参数为起始的索引(从 1 开始),第三个参数为截取的长度,不传默认截取后面全部字符串。

SELECT SUBSTR("panda", 3); -- nda
SELECT SUBSTR("panda", 3, 2); -- nd
(5) LEFT 和 RIGHT

LEFT 函数和 RIGHT 函数分别代表在字符串取左边或右边的规定位数,第一个参数为源字符串,第二个参数为规定的位数。

SELECT LEFT("panda12345", 5); -- panda
SELECT RIGHT("panda12345", 5); -- 12345
(6) INSTR

INSTR 函数用于查找某个字符串在一个源字符串中的起始(第一个匹配到的)索引,第一个参数为源字符串,第二个参数为查询字符串,查询不到返回 0。

SELECT INSTR("panda", "a"); -- 2
SELECT INSTR("panda", "x"); -- 0
(7) LTRIM、RTRIM 和 TRIM

LTRIM 函数用于去掉字符串左侧空格,RTRIM 用于去掉字符串右侧空格,TRIM 用于去掉字符串两侧的空格,如果 TRIM 的参数将两个字符串使用 FROM 连接,则代表去掉右侧字符串左右两侧的左侧字符串(说的有点绕,看例子)。

SELECT LTRIM("  panda"); -- panda
SELECT RTRIM("panda  "); -- panda
SELECT TRIM("  panda  "); -- panda
SELECT TRIM("@" FROM "@@panda@@"); -- panda
(8) LPAD 和 RPAD

LPAD 函数和 RPAD 函数分别用于向源字符串的左、右按照规定字符串的长度填充定义的字符。

SELECT LPAD("panda", 10, "@"); -- @@@@@panda
SELECT RPAD("panda", 10, "@"); -- panda@@@@@
(9) REPLACE

REPLACE 函数用于替换某字符串的部分字符,第一个参数为源字符串,第二个参数为被替换字符,第三个参数为替换字符。

SELECT REPLACE("panda", "a", "e"); -- pende
(10) 综合练习

查询 id 为 3 学生的邮箱域名。

SELECT SUBSTR(`email`, INSTR(`email`, "@") + 1)
FROM `student`
WHERE `id` = 3;

-- qq.com

将 student 表中的邮箱地址全部由小写改成大写。

UPDATE `student`
SET `email` = UPPER(`email`);

给 student 表新增一列 level,类型为 varchar,值为 1-1、1-2、1-3、2-1、2-2 等,按照 level 列值中 - 的前半段正序排列,后半段逆序排列。

SELECT `level`,
SUBSTR(`level`, 1, INSTR(`level`, "-") - 1),
SUBSTR(`level`, INSTR(`level`, "-") + 1)
FROM `student`
ORDER BY
SUBSTR(`level`, 1, INSTR(`level`, "-") - 1) ASC,
SUBSTR(`level`, INSTR(`level`, "-") + 1) DESC;

将 pandashen 转换成 Panda_Shen,将两个单词拆开,并实现首字母大写,其他字符小写,然后用 _ 拼接。

SELECT
CONCAT(
    CONCAT(
        UPPER(SUBSTR(SUBSTR("pandashen", 1, 5), 1, 1)),
        SUBSTR(SUBSTR("pandashen", 1, 5), 2)
    ),
    "_",
    CONCAT(
        UPPER(SUBSTR(SUBSTR("pandashen", 6), 1, 1)),
        SUBSTR(SUBSTR("pandashen", 6), 2)
    )
);

-- Panda_Shen

2、数学函数

(1) FORMAT

FORMAT 函数用于将数字格式化,第一个参数为要格式化的数字,第二个参数为保留的小数位数,返回值为字符串,整数部分每三位使用 , 分隔。

SELECT FORMAT(100000, 2); -- 100,000.00
SELECT FORMAT(100.31111, 3); -- 100.311
SELECT FORMAT(100.31111, 0); -- 100
SELECT FORMAT(423423234.65534453, 2); -- 423,423,234.66
(2) CEIL 和 FLOOR

CEIL 函数为向上取整,FLOOR 函数为向下取整。

SELECT CEIL(2.4); -- 3
SELECT FLOOR(2.4); -- 2
(3) ROUND 和 TRUNCATE

ROUND 函数为四舍五入,TRUNCATE 函数为小数截断,第一个参数为截断的数字,第二个参数为保留的小数位数。

SELECT ROUND(2.1); -- 2
SELECT ROUND(2.5); -- 3
SELECT TRUNCATE(1.66, 0); -- 1
SELECT TRUNCATE(1.66, 1); -- 1.6
SELECT TRUNCATE(1.66, 2); -- 1.66
SELECT TRUNCATE(1.66, 3); -- 1.66
(4) POWER

POWER 函数用于幂运算,第一个参数为底数,第二个参数为指数。

SELECT POWER(2, 3); -- 8
(5) MOD

MOD 函数用于取余运算,第一个参数为被除数,第二个参数为除数。

SElECT MOD(10, 3); -- 1

3、日期函数

(1) NOW、CURDATE 和 CURTIME

NOW 函数用于获取当前的时间,格式为 yyyy-mm-dd hh:mm:ss,CURDATE 函数用于获取当前日期,格式为 yyyy-mm-dd hh:mm:ss,CURTIME 函数用于获取当前时间,格式为 hh:mm:ss,返回类型均为日期格式。

SELECT NOW(); -- 2018-08-09 19:23:18
SELECT CURDATE(); -- 2018-08-09
SELECT CURTIME(); -- 19:25:31
(2) DATE_ADD

DATE_ADD 函数用于增加时间,即将时间求和,第一个参数为 yyyy-mm-dd hh:mm:ss 格式的时间,第二个参数为时间间隔,INTERVAL 关键字代表时间间隔,后面跟上数字,单位为 DAY、MONTH、YEAR 等,返回类型为字符串。

SELECT DATE_ADD(NOW(), INTERVAL 365 DAY); -- 2019-08-09 19:30:15
SELECT DATE_ADD(NOW(), INTERVAL 1 MONTH); -- 2018-09-09 19:30:15
SELECT DATE_ADD(NOW(), INTERVAL 1 YEAR); -- 2019-08-09 19:30:15
(3) STR_TO_DATE

STR_TO_DATE 函数可以将一个日期格式的字符串转换成日期,第一个参数为日期格式的字符串,第二个参数为日期的格式描述,如 %Y-%m-%d,传入的日期字符串的格式与日期格式描述必须保持一致。

SELECT STR_TO_DATE("2018-08-09", "%Y-%m-%d"); -- 2018-08-09
SELECT STR_TO_DATE("2018/08/09", "%Y/%m/%d"); -- 2018-08-09
SELECT STR_TO_DATE("2018.08.09", "%Y.%m.%d"); -- 2018-08-09

从 student 表中查询一个生日(列名为 birthday)为 1982 年 9 月 3 的学生信息。

SELECT *
FROM `student`
WHERE `birthday` = STR_TO_DATE('09-03 1982','%m-%d %Y');

-- 结果查到了黄蓉的信息

格式描述参考下表:

序号格式符功能
1%Y4 位的年份
2%y2 位的年份
3%m月份(01,02)
4%c月份(1,2)
5%d日(01,02)
6%H小时(24 小时制)
7%h小时(12 小时制)
8%i分钟(00,01)
9%s秒(00,01)
(4) DATE_FORMAT

DATE_FORMAT 函数与 STR_TO_DATE 作用正好相反,是将一个日期类型按照格式描述转换成日期字符串,第一个参数为日期对象,第二个参数为日期的格式描述。

SELECT DATE_FORMAT(STR_TO_DATE("2018-08-09", "%Y-%m-%d"), "%Y年%m月%d日");

-- 2018年08月09日
(5) DATEDIFF

DATEDIFF 函数用于计算时间间隔,两个参数均为日期对象,得到的结果为第一个与第二个的差值,单位为 “天”。

SELECT DATEDIFF(NOW(), STR_TO_DATE("2018-08-08", "%Y-%m-%d")); -- 1

通过查询 student 的 birthday 列计算每个人的年龄(周岁)。

SELECT FLOOR(DATEDIFF(NOW(), `birthday`) / 365)
FROM `student`;
(6) 返回日期中指定的部分

下面方法传入参数均为日期对象,返回的时间中对应的部分均为字符串。

  • YEAR:返回年;
  • MONTH:返回月;
  • DAY:返回日;
  • HOUR:返回小时;
  • MINUTE:返回分钟;
  • SECOND:返回秒;
  • MONTHNAME:返回月份名称(英文)。
SELECT YEAR(NOW()); -- 2018
SELECT MONTH(NOW()); -- 8
SELECT DAY(NOW()); -- 9
SELECT HOUR(NOW()); -- 19
SELECT MINUTE(NOW()); -- 48
SELECT SECOND(NOW()); -- 53
SELECT MONTHNAME(NOW()); -- August
(7) 综合练习

查询 student 表中出生月份是 9 月的学生。

SELECT *
FROM `student`
WHERE MONTH(`birthday`) = 9;

查询 student 表中生日是今天的学生。

SELECT *
FROM `student`
WHERE MONTH(NOW()) = MONTH(`birthday`) AND DAY(NOW()) = DAY(`birthday`);

在 student 表中查询年龄超过 18 岁的男同学。

-- 写法 1:求生日与现在时间的差值转换成年与年龄比较
SELECT *
FROM `student`
WHERE DATEDIFF(NOW(), `birthday`) / 365 > 18;
-- 写法 2:给生日加上 18 年看看是否大于今天的时间
SELECT *
FROM `student`
WHERE DATE_ADD(`birthday`, INTERVAL 18 YEAR) < NOW();
-- 写法 3:获取今天时间的年份和生日的年份做差,看是否大于 18
SELECT *
FROM `student`
WHERE YEAR(NOW()) - YEAR(`birthday`) > 18;

4、数据库辅助函数

(1) CONNECTION_ID

连接每个数据库都会分配对应的连接号,我们称为连接 ID,CONNECTION_ID 函数可以帮我们获取连接 ID。

SELECT CONNECTION_ID(); -- 10
(2) DATABASE

DATABASE 函数用于查看当前的连接的数据库,返回数据库名称。

SELECT DATABASE(); -- school
(3) VERSION

VERSION 函数用来查看当前 MySQL 数据库的版本号。

SELECT VERSION(); -- 5.5.61
(4) LAST_INSERT_ID

LAST_INSERT_ID 可以获取上次向表中(任意表)插入数据时,插入数据的 id 号。

select LAST_INSERT_ID(); -- 0
(5) USER 和 PASSWORD

USER 用于查询当前数据库登录的用户。

SELECT USER(); -- root@

在 MySQL 数据库中存在一张表存放着 MySQL 当前所有的用户,可以通过下面命令查询。

SELECT * FROM mysql.user;

通过查询结果可以看出密码的位置存储的是密文,如果要修改密码需要将设置的密码转换成密文进行存储,PASSWORD 函数就是来做这件事的,修改密码命令如下。

UPDATE FROM mysql.user
SET `password` = PASSWORD("123456");
(6) MD5

MD5 可以将传入的字符串进行一个 MD5 散列算法的转换并输出。

SELECT MD5("panda"); -- ce61649168c4550c2f7acab92354dc6e

5、流程控制函数

(1) IF

IF 函数可以根据传入的判断条件在两个结果中进行选择输出。

SELECT IF(1 > 2, "yes", "no"); -- no
(2) CASE、WHEN、THEN、ELSE 和 END

CASE、WHEN、THEN、ELSE 和 END 共同组成了一个流程控制函数,可以代替多个 IF,CASE 为条件判断起始关键字,WHEN 为判断条件关键字(可以有多个),THEN 为输出结果关键字,ELSE 为默认输出关键字,END 为流程结束关键字。

SELECT `grade`,
CASE
WHEN `grade` > 90 THEN "优"
WHEN `grade` > 80 THEN "良"
WHEN `grade` > 70 THEN "中"
WHEN `grade` > 60 THEN "及格"
ELSE "不及格"
END
FROM `score`;

6、自定义函数

(1) 规则
  • 自定义函数是对 MySQL 的扩展,使用方式和内置函数相同;
  • 函数必须要有参数和返回值,函数可以接收任意类型的值和参数,返回值只能有一个;
  • 函数体由合法的 SQL 语句组成,可以包含声明、循环和流程控制,也可以是 SELECT 或 INSERT 语句,如果函数体是复合结构(多条语句)要用 BEGIN...END。
(2) 语法
CREATE FUNCTION FUNC_NAME RETURNS {String|Integer}
BODY
RETURN VALUE

CREATE FUNCTION 为创建函数关键字,FUNC_NAME 为函数的名字,RETURNS 为返回类型关键字,“{ }” 中的内容为返回值类型,如 varchar 等,BODY 代表函数体,RETURN VALUE 代表返回值。

(3) 实例

写一个自定义函数用于获取中文格式的当前时间。

-- 函数 ZHNOW
CREATE FUNCTION ZHNOW() RETURNS VARCHAR(64)
RETURN DATE_FORMAT(NOW(), "%Y年%m月%d日");

-- 使用 ZHNOW
SELECT ZHNOW(); -- 2018年08月10日

实现一个自定义函数对两个数字进行相乘运算并将结果返回。

-- 函数 MYPRODUCT,参数为两个数字
CREATE FUNCTION MYPRODUCT(n INT, m INT) RETURNS INT
RETURN n * m;

-- 使用 MYPRODUCT
SELECT MYPRODUCT(2, 5); -- 10

针对上面的 course 学科表,写一个自定义函数用来增加学科并返回增加数据的 id 值。

-- 函数 ADD_COURSE,参数为添加课程的名称
CREATE FUNCTION ADD_COURSE(name VARCHAR(32)) RETURNS INT
BEGIN
INSERT INTO `course` (`name`)
VALUES (name);
RETURN LAST_INSERT_ID();
END

-- 使用 ADD_COURSE
SELECT ADD_COURSE("体育"); -- 4

聚合函数

上一节中的函数都是普通函数,多用于操作表达式后返回结果,而聚合函数更多是对一组值进行计算,并返回计算后的值,一般用来统计数据,使用难度要大于普通函数。

1、SUM

SUM 函数用于累加所有行的值。

还是以上面的 score 表为例,我们取出 student_id 值为 1 的学生全部科目的总成绩。

SELECT SUM(`grade`)
FROM `score`
WHERE `student_id` = 1; -- 260

其实上面的操作是分为两部分进行,首先先查出 student_id 为 1 的所有学科的成绩,在对这些成绩进行求和计算后返回。

2、AVG

AVG 函数用于计算所有行的平均值。

在 score 表中查询 student_id 值为 3 的学生全部科目成绩的平均值。

SELECT AVG(`grade`)
FROM `score`
WHERE `student_id` = 3; -- 80

3、MAX 和 MIN

MAX 和 MIN 分别用于计算所有行的最大值和最小值。

在 score 表中查询 student_id 值为 2 的学生全部科目成绩的最大值和最小值。

SELECT MAX(`grade`), MIN(`grade`)
FROM `score`
WHERE `student_id` = 2; -- 100 40

4、COUNT

COUNT 按照某一列统计所有行的总条数,如果参照的列值为 null 则不统计在内。

在 score 表中查询 student_id 值为 1 的学生成绩总数。

SELECT COUNT(`grade`)
FROM `score`
WHERE `student_id` = 1; -- 3

SQL 语句之分组聚合

1、分组

分组查询就是按某一列或某几列的值进行分组,相同的值分为一组,然后可以对组内使用聚合函数分别进行统计。

以 score 表为例,分组表示图如下:

在这里插入图片描述

语法:

SELECT 列名, 查询表达式
FROM  <表名>
GROUP BY <分组字段>

GROUP BY 关键字用于对筛选后的结果进行分组。

例子:

统计 score 表中每位同学的平均成绩(单列分组,对 student_id 进行分组)。

SELECT `student_id`, AVG(`grade`)
FROM `score`
GROUP BY `student_id`;

统计 score 表中每门课程的最高分(单列分组,对 course_id 进行分组),并按照分数从低到高排序。

SELECT `course_id`, MAX(`grade`)
FROM `score`
GROUP BY `course_id`
ORDER BY `grade` ASC;

统计 student 表中各省男女同学人数(多列分组,按照 province 和 gender 进行分组)。

SELECT `province`, `gender`, COUNT(*)
FROM `student`
GROUP BY `province`, `gender`;

COUNT 中的 * 代表任意一列。

2、分组筛选

语法:

SELECT 列名, 查询表达式
FROM  <表名>
WHERE  <条件>
GROUP BY <分组字段>
HAVING 分组后的过滤条件
ORDER BY 列名 [ASC, DESC]
LIMIT 偏移量, 条数

WHERE 用于过滤掉不符合条件的记录,HAVING 用于过滤分组后的记录。

注意:上面查询的关键字不一定每条查询语句都要有,但是如果有其中的某些关键字,一定要按照上面的顺序进行。

例子:

统计 student 表中学生人数多于一个的省份。

SELECT `province`, COUNT(*)
FROM `student`
GROUP BY `province`
HAVING COUNT(*) > 1;

统计 score 表中不及格次数大于 1 的学生按逆序排列并取前 3 条。

SELECT `student_id`, COUNT(*)
FROM `score`
WHERE `grade` < 60
GROUP BY `student_id`
HAVING COUNT(`grade`) > 1
ORDER BY COUNT(`grade`) DESC
LIMIT 0, 3;

SQL 语句之子查询

子查询的注意点:

  • 子查询是出现在其他 SQL 语句中的 SELECT 语句;
  • 子查询嵌套在查询内部,且必须写在圆括号中,外层可以是 SELECT、INSERT、UPDATE、SET 等;
  • 子查询可以包含多个关键字或条件;
  • 子查询可以返回常量、一行数据、一列数据或其它子查询(返回多行数据需使用其他关键字处理)。

1、比较运算符连接子查询

在查询通过 WHERE 进行条件筛选时,可以使用比较运算符连接子查询。

查询年龄大于平均年龄的学生。

SELECT *
FROM `student`
WHERE YEAR(NOW()) - YEAR(`birthday`) > (
    SELECT AVG(YEAR(NOW()) - YEAR(`birthday`))
    FROM `student`
);

2、IN 和 NOT IN

当查询一张表的数据需要另一张表中的数据作为筛选条件时,可以在查询时通过 IN 和 NOT IN 关键字连接子查询。

查询 student 有不及格成绩的学生信息。

SELECT *
FROM `student`
WHERE `id` IN (
    SELECT DISTINCT `student_id`
    FROM `score`
    WHERE `grade` < 60
);

-- 结果查到了黄蓉

上面例子查到了 “黄蓉” 同学的信息,如果将 IN 修改为 NOT IN 则会查询到除 “黄蓉” 以外其他同学的信息。

查询 student 表中在 score 表中有成绩的学生信息。

SELECT *
FROM `student`
WHERE student.id IN (
    SELECT DISTINCT `student_id`
    FROM `score`
);

3、EXISTS 和 NOT EXISTS

EXISTS 和 NOT EXISTS 关键字用于连接子查询,代表 “存在” 或 “不存在” 的意思,接收的子查询返回为数据为布尔值。

拿上面查询 student 表在 score 表中有成绩学生信息的例子,使用 EXISTS 实现查询。

SELECT *
FROM `student`
WHERE EXISTS (
    SELECT `student_id`
    FROM `score`
    WHERE score.student_id = student.id
);

IN、NOT IN 与 EXISTS、NOT EXISTS 比较,后者的性能更高,查询速度更快,因为判断是在子查询内部,EXISTS、NOT EXISTS 只需要判断布尔值就可以了,IN、NOT IN 在子查询返回数据的基础上还要再次过滤。

4、ALL、SOME 和 ANY

当子查询返回了多条数据的时候,可以使用 ALL、SOME 和 ANY 关键字作为比较运算符和子查询之间的连接。

  • ALL 关键字代表全部,即查询的数据筛选条件要去和所有子查询返回的比较并都满足;
  • SOME 关键字代表某些,查询数据筛选条件只要满足子查询返回数据的某些条即可;
  • ANY 关键字代表任何一个,查询数据的筛选条件只要满足子查询返回数据的任意一条即可。

查询 student 表中年龄大于等于所有人的学生信息。

SELECT *
FROM `student`
WHERE `age` >= ALL (
    SELECT `age`
    FROM `student`
);

-- 结果查到了欧阳锋

查询 student 表中年龄大于某些人的学生信息。

SELECT *
FROM `student`
WHERE `age` > SOME (
    SELECT `age`
    FROM `student`
);

-- 结果查到除杨过以外的所有人(因为杨过年龄最小)

查询 student 表中年龄大于任意一个人的学生信息。

SELECT *
FROM `student`
WHERE `age` > ANY (
    SELECT `age`
    FROM `student`
);

-- 返回结果同 SOME 没区别

表连接

1、连接类型

在 MySQL 中的表连接类型:

  • INNER JOIN:内连接,代表取两张关联表的交集,可以用 JOIN 关键字代替;
  • LEFT:左外连接,代表取两张表的交集后再和左侧表求并集,即包含左侧表全部数据;
  • RIGHT:右外连接,代表取两张表的交际后再和右侧表求并集,即包含右侧表全部数据。

三种连接类型表示如下图:

在这里插入图片描述

2、连接条件 ON

ON 关键字用来设定表的连接条件,也可以使用 WHERE 对结果进行过滤的方式来代替。

(1) 内连接

对 student 和 score 两张表使用内连接。

SELECT *
FROM `student`
INNER JOIN `score` ON student.id = score.student_id;

查询结果如下:


内连接查询结果

(2) 左外连接

对 student 和 score 两张表使用左外连接。

SELECT *
FROM `student`
LEFT JOIN `score` ON student.id = score.student_id;

查询结果如下:

在这里插入图片描述

(3) 右外连接

对 student 和 score 两张表使用右外连接。

SELECT *
FROM `student`
RIGHT JOIN `score` ON student.id = score.student_id;

查询结果如下:

在这里插入图片描述

(4) 多表连接案例

连接 student、score 和 course 三张表,分别查询学生姓名、学科和分数。

SELECT student.name, course.name, score.grade
FROM `score`
INNER JOIN `student` ON student.id = score.student_id
INNER JOIN `course` ON course.id = score.course_id;

总结

到此 MySQL 系列文章的第二篇就结束了,本篇的大部分都是和操作数据库的 SQl 语句相关的知识点,里面涵盖了基本的增、删、改、查以及函数、聚合函数的应用等,如果记不住的话(当然我也记不住,只是负责替大家和我自己整理)建议收藏,在使用时随时查阅,这一篇的内容对于前端而言,可以说基本够用了,如果你对数据库还有兴趣,想了解关于表的设计的相关思想,期待我的下一篇 《MySQL —— 简单聊一聊数据库设计》 更新吧。


VOLTE信令流程-IMS注册篇(五) 目录 VOLTE信令流程-IMS 注册 VOLTE信令流程-IMS 注册/注销 VOLTE信令流程-VoLTE呼叫流程 VoLTE-VoLTE VoLTE-CS CS-VoLTE CS-CS VOLTE信令流程 VOLTE信令流程-VOLTE-VOLTE信令 VOLTE信令流程-INVITE详细信息 VOLTE信令流程-eSRVCC信令流程 VOLTE信令流程-IP短信 VOLTE信令流程-IMS 注册 IMS注册流程简述  获取鉴权向量 IMS用户将注... 阅读详情

相关推荐

2D激光slam四种算法建图效果对比

2d激光slam四种算法建图比较

m0_73791170的博客 8448

MySQL学习笔记(6)-SQL基本操作

SQL基本操作基本操作CRUD将SQL的基本操作根据操作对象进行分类,分为三类:库操作,表操作(字段),数据操作库操作对数据库的增删改查。新增数据库基本语法Create database 数据库名字 [表选项];Create database 数据库名字 [库选项];库选项:用来约束数据库,分为两个选项    字符集设定:charset/character set 具体字符集(数据存储的编码格式)...

Jak的博客 359

西门子Industrial Copilot实战:5个工业场景下的AI效率提升案例

本文通过五个工业场景实战案例,深入解析西门子Industrial Copilot如何将工业智能转化为实际生产力。从自动化配置、预测性维护到能源优化与人机交互,这位AI助手显著缩短工程周期、提升设备可用率并降低运营成本,展示了其在工业领域系统化、工程化的落地价值。

3c4x5z6v7b的博客 925

MySQL零基础从入门到精通,看完这篇直接毕业!(图文并茂,实战教学)

数据表的创建 1.创建数据表语法 Createtable表名( 字段名1数据类型[完整性约束条件], 字段名2数据类型[完整性约束条件], .... 字段名n数据类型[完整性约束条件] )characterset字符集collate校对规则; 创建数据库 Createdatabaseitcast; 选择数据库 Useitcast; 2.创建一个用于存储学生成绩的表tb_grade Createtabletb_grade1( Idint(11), Namevarchar(

陈新科的博客 5545

Vivado+VCS+Verdi三件套实战:如何高效仿真AXI VIP并快速查看波形

本文详细介绍了如何利用Vivado+VCS+Verdi工具链高效仿真AXI VIP并快速查看波形。通过环境配置、Vivado工程准备、VCS编译与仿真优化以及Verdi波形分析技巧,实现仿真速度的数量级提升,显著提高FPGA开发效率。

red88的博客 1000

常见机械臂模型不用找!Mujoco这儿都有!

高质量的模型集合,franka panda,so-arm100,ur之类的机械臂都有。常见机械臂模型不用找!Mujoco这儿都有!大概346M,网速不行的可以下载zip。

darcsdn 992

Mysql select查询语句单表操作指南

单表查询 1 简介 在当前工作环境下,程序员在开发项目时一般需要保存数据到某种数据库中,而常用的数据库有Oracle,Mysql,SQL Server,DB2,MongoDB等数据库。MySQL数据库管理系统是由瑞典的MySQL AB公司开发的,但是几经辗转最后成为Oracle的产品。由于MySQL的开源、跨平台的特性,使得MySQL的使用非常普遍。本文档主要介绍的是在Mysql数据库中...

不当初 1356

【学习记录】IIC驱动ICM42670+卡尔曼滤波+四元数姿态角解算

ICM42670陀螺仪可以使用iic驱动,单片机平台使用GD32f305VE。

liarsup的博客 8261

数据库MySQL总结(一)SQL语句

目录 一、一些命令 二、SQL结构化查询语言 1、DDL 数据库定义语言 针对结构(库、表)的增删改查 create drop alter show 有关库的增删改查 (1)创建库 (2)删除库 (3)查看库 有关表的增删改查 (1)创建表 (2)删除表 (3)修改表 (4)查看表 2、DML 数据操作语言 针对数据的增删改查 (1)插入数据 ...

lisaaaaaas0405的博客 9462

【GameFramework框架内置模块】8、文件系统(File System)

最近好忙,鸽了好久。不能颓废了,继续发力。今天分享的是GF框架的文件系统。首先,引用比较官方的说法:GF的FileSystem虚拟文件系统,使用类似磁盘存储的感念对零散的文件进行集中管理,优化资源加载时产生的内存分配,也可以对资源进行局部片段加载,极大的提升了资源加载的性能。通俗点讲就是,我这个模块就是加载磁盘文件的,优化加载时产生的内存分配。那么,它是怎么优化的呢?

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 2452

ubuntu-emto-cpa 测试和使用(单核运行)

ubuntu-emto-cpa 测试和使用(单核运行)

qq_45834835的博客 1400

第12章 MySQL基础语句

SQL语句结构 1.数据查询语言(DQL:Data Query Language) 也称为“数据检索语句”,包括SELECT , WHERE , ORDER BY ,GROUP BY ,HAVING 2.数据操作语言(DML:Data Manipulation Language) 包括动词INSERT,UPDATE,DELETE,它们分别用于添加,修改和删除表中的行。也称为动作查询语言。 3.事务处理语言(TPL):由多条SQL语句组成的整体。 它的语句能被确保被DML语句影响的表所有行为及时得到更新

537

30分钟用 Restful ABAP Programming(RAP)模型开发一个支持增删改查的 Fiori 应用

2016年时,Jerry曾经写过一系列关于SAP Fiori Smart Template(现在更名为Fiori Elements了)的博客,介绍了所谓的MDD开发方法论 - Metadata Driven Development,即通过开发维护了对应annotation(注解)的CDS view,结合SAP WebIDE,能够花费最少的编程代价,就能够在短时间内获得一个支持增删改查的Fiori应......

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5951

【SQL】Mysql中一条sql语句的执行过程

假设写完 redo log 后,机器挂了,binlog 日志没有被写入,那么机器重启后,这台机器会通过 redo log 恢复数据,但是这个时候 binlog 并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。然后拿到查询的语句,把 age 改为 19,然后调用引擎 API 接口,写入这一行数据,InnoDB 引擎把数据保存在内存中,同时记录 redo log,此时 redo log 进入 prepare 状态,然后告诉执行器,执行完成了,随时可以提交。

double222222的博客 3442

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

MySQL如何跟踪sql语句

在项目开发中,难免会遇到在数据库服务器端跟踪sql执行语句的需求,通过跟踪sql执行语句,我们可以确定当上层应用在执行sql语句时,数据库端是否执行了sql语句,执行的sql语句是否有错误等等。总之,在数据库端跟踪sql执行语句极大的便利了数据库逻辑代码编写中的错误排查。 我们都知道在SQL SERVER下跟踪sql采用事件探查器,那么在mysql下如何跟踪执行的sql语句了?

andieguo的专栏 1万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

mysql跟踪sql语句_mysql跟踪执行的sql语句

修改my.cnf配置文件/usr/local/mysql/bin/mysql --verbose --help | grep -A 1 'Default options'Default options are read from the following files in the given order:/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql...

weixin_30995363的博客 1547

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

MySQL——三、SQL语句(上篇)

本篇为sql语句基本内容上篇,详细内容包含了:SQL语句基础 SQL简介1、 2、SQL语句分类 3、SQL语句的书写规范 数据库操作 三、MySQL 字符集 1、变量 2、utf8和utf8mb4的区别 四、数据库对象 五、SELECT语句 1、简单的SELECT语句 2、SQL函数 2.1聚合函数 2.2 数值型函数 2.3 字符串函数 2.4 日期和时间函数 2.5 流程控制函数等等

钟言的博客 4115

MySQL常用的sql语句

SQL语句核心功能与实用技巧摘要: SQL语句主要分为四类:数据查询(SELECT)、数据操作(INSERT/UPDATE/DELETE)、数据定义(CREATE/ALTER)和数据控制(GRANT/COMMIT)。基础查询包括条件筛选、排序分页和聚合分组,多表连接可实现复杂关联查询。DML语句完成增删改操作,DDL定义数据库结构,DCL管理权限事务。高级技巧包含子查询、CTE和窗口函数,优化建议着重索引创建和查询效率提升。掌握这些语句可高效完成数据检索、业务逻辑实现和性能优化,是数据库操作的核心技能。

simpler0808的博客 1669

什么是SQL,什么是MYSQL?SQL执行语句的过程是什么?

SQL是一种用于管理关系型数据库系统(RDBMS)的标准化语言。它允许用户创建、更新、查询和管理数据库中的数据。SQL语言使用简洁的语法和关键字,通过指定需要执行的操作来与数据库进行交互。

2301_77899321的博客 1196

mysql监视执行sql语句_监控mysql执行的sql语句

linux平台 监控mysql执行的sql语句 为了做好配合开发做性能和功能测试,方便监控正在执行的sql语句, 可以在/etc/mysqld中添加如下: log =/usr/local/mysql/var21005/mysql.log 就可以使用: tail -f mysql.log 来监控了 www.2cto.com 如果需要监控慢查询可以添加如下内容: log-slow-q...

weixin_34773479的博客 3412

MySQL语法及SQL语句总结

Mysql基本命令及SQL语句总结

2301_77004154的博客 2516

mysql 批处理sql语句_MySQL批处理SQL语句

MySQL 支持批处理的模式执行一批SQL语句,下面的例子就是实验MySQL如何在windows下批处理执行SQL语句。create table test(id int,name varchar(20));insert into test values(1,'watson');batchfile.txt里包含下面的一些SQL 语句,此文件放在windows系统的c:/batchmysql/batc...

weixin_36098127的博客 424

图解MySQL的SQL语句执行全流程,看看自己的SQL语句是如何执行的

MySQL作为一种广泛使用的开源关系型数据库管理系统,其SQL语句的执行流程对于理解数据库性能优化、错误排查以及数据库设计都至关重要。

小白的大数据之旅的博客 1417

MySql 常用SQL语句、 SQL优化

SQL语句主要分为五类:数据定义语言(DDL)用于管理数据库结构,数据查询语言(DQL)用于检索数据,数据操纵语言(DML)用于增删改数据,数据控制语言(DCL)用于权限管理,事务控制语言(TCL)用于事务管理。键约束方面,超键能唯一标识行,候选键是最小超键,主键是选定的候选键,外键则关联表间数据。SQL约束包括非空、唯一、主键、外键、检查及默认值约束,确保数据完整性。

weixin_44289947的博客 1329
上一篇: MySQL —— 数据库基础
下一篇: MySQL —— 简单聊一聊数据库设计
Panda Shen
博客等级 码龄10年 18粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值