JAVA进阶 MySQL数据库编程技术

目录

一、创建删除数据库

1.1创建数据库

1.2查看数据库

1.3 删除数据库

1.4 选择数据库

二、MySQL中的数据类型

2.1 整数类型

2.2浮点类型

2.3字符类型

2.4日期类型

 2.5二进制数据

三、对表的操作

3.1 创建表

3.2删除表

3.3修改表

3.3.1修改表名

3.3.2修改列名

3.3.3修改列类型

3.3.4添加新列

3.3.5删除指定列

四、MySQL中的约束

4.1添加主键约束(Primary Key)

4.2主键自增长

4.3 删除主键

4.4添加外键约束(Foreign Key)

4.5删除外键约束 

4.6添加唯一性约束(Unique)

4.7删除唯一性约束

4.8添加非空约束

4.9删除非空约束

4.10在创建表时添加约束

五、 MySQL中DML操作 

5.1添加数据(INSERT)

5.1.1选择插入

5.1.2完全插入

5.2默认值处理(DEFAULT) 

5.2.1创建表时指定列的默认值

5.2.2添加新列并指定默认值 

5.2.3插入数据时的默认值处理

5.3更新数据(UPDATE)

5.4删除数据(DELETE)

5.4.1DELETE删除数据

5.4.2TRUNCATE清空表

5.4.3清空表时DELETE与 TRUNCATE 区别

六、MySQL中的DQL操作

6.1SELECT基本查询

6.1.1SELECT语句的功能

6.1.2SELECT基本语法

6.1.3选择所有列

6.1.4选择指定列

6.1.5查询中的算术表达式

6.1.6运算符的优先级

6.1.7MySQL中定义空值

6.1.8算数表达式中的空值                

6.1.9MySQL中的别名

6.1.10MySQL中去除重复

6.1.11查询中的行选择

6.1.12MySQL中的比较条件

6.1.13其他比较条件

6.1.14逻辑条件

6.1.15优先规则

6.1.16使用 ORDER BY 排序

6.1.17练习部分

七、MySQL函数

7.1 单行函数

7.1.1单行函数的分类

 7.1.2字符函数

7.1.3数字函数

7.1.4日期函数

7.1.5转换函数

7.1.6通用函数

7.1.7单行函数练习

7.2多行函数  

八、多表查询

8.1 SQL92标准中的查询

8.1.1等值连接

8.1.2非等值连接

8.1.3自连接

8.2SQL99标准中的查询

8.2.1交叉连接

8.2.2自然连接

8.2.3内连接

8.2.4左外连接和右外连接

8.2.5多表连接查询练习


一、创建删除数据库

1.1创建数据库

CREATE DATABASE  数据库名 DEFAULT CHARACTER SET  字符编码;

1.2查看数据库

show databases;

1.3 删除数据库

DROP DATABASE  数据库名称;

1.4 选择数据库

USE 数据库名;

二、MySQL中的数据类型

2.1 整数类型

MySQL数据类型含义(有符号)
tinyint(m)1个字节 范围(-128~127);常用来表示性别、状态
smallint(m)2个字节 范围(-32768~32767)
mediumint(m)3个字节 范围(-8388608~8388607)
int(m)4个字节 范围(-2147483648~2147483647)
bigint(m)8个字节 范围(+-9.22*10的18次方)

数值类型中的长度 m 是指显示长度,并不表示存储长度,只有字段指定 zerofill 时有用

例如: int(3) ,如果实际值是 2 ,如果列指定了 zerofill ,查询结果就是 002 ,左边用 0 来 填充

2.2浮点类型

MySQL数据类型含义
float(m,d)单精度浮点型 8位精度(4字节) m总个数,d小数位
double(m,d)双精度浮点型 16位精度(8字节) m总个数,d小数位

2.3字符类型

MySQL数据类型含义
char(n)固定长度,最多255个字符(必须给定n)
tinytext可变长度,最多255个字符
varchar(n)可变长度,最多65535个字符(必须给定n)
text可变长度,最多65535个字符
mediumtext可变长度,最多2的24次方-1个字符
longtext可变长度,最多2的32次方-1个字符

char和varchar:


  1. char长度固定, 即每条数据占用等长字节空间;适合用在身份证号码、手机号码等定长。
  2. varchar可变长度,可以设置最大长度;适合用在长度可变的属性。
  3. text不设置长度, 当不知道属性的最大长度时,适合用text。例如:描述和简介等

按照查询速度: char最快, varchar次之,text最慢。

字符串型使用建议:


  1. 经常变化的字段用varchar
  2. 知道固定长度的用char
  3. 尽量用varchar
  4. 超过255字符的只能用varchar或者text
  5. 能用varchar的地方不用text

2.4日期类型

MySQL数据类型含义
date日期 YYYY-MM-DD
time时间 HH:MM:SS
datetime日期时间 YYYY-MM-DD HH:MM:SS
timestamp时间戳YYYYMMDD HHMMSS

timestamp时间戳在存储日期时,是不考虑时区的。只要项目不涉及到跨时区的用datetime2.5二进制数据(BLOB)

 2.5二进制数据

  1. BLOB和TEXT存储方式不同,TEXT以文本方式存储,英文存储区分大小写,而Blob是以二进制方式存储,不分大小写。
  2. BLOB存储的数据只能整体读出。
  3. TEXT可以指定字符集,BLOB不用指定字符集。

三、对表的操作

3.1 创建表

CREATE TABLE 表名(列名 类型,列名 类型......);

3.2删除表

DROP TABLE 表名;

3.3修改表

3.3.1修改表名

ALTER TABLE  旧表名 RENAME  新表名;

3.3.2修改列名

ALTER TABLE  表名 CHANGE COLUMN  旧列名 新列名 类型;

3.3.3修改列类型

ALTER TABLE  表名 MODIFY  列名 新类型;

3.3.4添加新列

ALTER TABLE  表名 ADD COLUMN  新列名 类型;

3.3.5删除指定列

ALTER TABLE  表名 DROP COLUMN  列名;

四、MySQL中的约束

约束概述

数据库约束是对表中的数据进行进一步的限制,保证数据的正确性、有效性和完整性。

  1. 主键约束(Primary Key) PK

    主键约束是使用最频繁的约束。在设计数据表时,一般情况下,都会要求表中设置一个主键。 主键是表的一个特殊字段,该字段能唯一标识该表中的每条信息。例如,学生信息表中的学号是唯一的。

  2. 外键约束(Foreign Key) FK

    外键约束经常和主键约束一起使用,用来确保数据的一致性。外键约束可以是空,但是不能添加参照表中不存在的数据。

  3. 唯一性约束(Unique)

    唯一约束与主键约束有一个相似的地方,就是它们都能够确保列的唯一性。与主键约束不同的是,唯一约束在一个表中可以有多个,并且设置唯一约束的列是允许有空值的。

  4. 非空约束(Not Null)

    非空约束用来约束表中的字段不能为空。

  5. 检查约束(Check)

    检查约束也叫用户自定义约束,是用来检查数据表中,字段值是否有效的一个手段,但目前 MySQL 数据库不支持检查约束。

4.1添加主键约束(Primary Key)

  1. 单一主键

    使用一个列作为主键列,当该列的值有重复时,则违反唯一约束。

  2. 联合主键

    使用多个列作为主键列,当多个列的值都相同时,则违反唯一约束。

ALTER TABLE  表名 ADD PRIMARY KEY(列名)

4.2主键自增长

MySQL 中的自动增长类型要求:

  • 一个表中只能有一个列为自动增长。
  • 自动增长的列的类型必须是整数类型。
  • 自动增长只能添加到具备主键约束与唯一性约束的列上。
  • 设置主键自增之后,往数据库添加数据时不需要我们手动添加主键了。
alter table 表名 modify 主键 类型 auto_increment;

4.3 删除主键

注意:

删除主键时,如果主键列具备自动增长能力,需要先去掉自动增长,然后在删除 主键。


alter table 表名 modify 主键列 类型;
ALTER TABLE  表名 DROP PRIMARY KEY;

4.4添加外键约束(Foreign Key)

ALTER TABLE  表名 ADD CONSTRAINT  约束名 FOREIGN KEY( 列 名 ) REFERENCES  参照的表名(参照的列名);

约束名是随便取的一般使用  表名_FK

例如:向 emp 表中的 dept_id 列添加外键约束。

alter table emp add constraint emp_fk foreign key(dept_id) references departments(department_id);

4.5删除外键约束 

ALTER TABLE  表名 DROP FOREIGN KEY  约束名;

4.6添加唯一性约束(Unique)

ALTER TABLE  表名 ADD CONSTRAINT  约束名 UNIQUE(列名);

约束名一般使用 :表名_UK

4.7删除唯一性约束

ALTER TABLE  表名 DROP KEY  约束名;

4.8添加非空约束

ALTER TABLE  表名 MODIFY  列名 类型 NOT NULL;

4.9删除非空约束

ALTER TABLE  表名 MODIFY  列名 类型 NULL;

4.10在创建表时添加约束

查看表的约束信息

SHOW KEYS FROM  表名;

示例:

创建 depts 表包含 department_id 该列为主键且自动增长,department_name 列不 允许重复,location_id 列不允含有空值。

create table depts(department_id int primary key auto_increment,department_name varchar(30) unique,location_id int not null);

五、 MySQL中DML操作 

5.1添加数据(INSERT)

5.1.1选择插入

根据需求向指定列插入数据。如果存在非空约束,则必须将该列插入数据。

INSERT INTO  表名(列名 1 ,列名 2 ,列名 3.....) VALUES(值 1 ,值 2 ,值 3......);

5.1.2完全插入

INSERT INTO  表名 VALUES(值 1 ,值 2 ,值 3......);

注意:


如果主键是自动增长,需要使用 default 或者 null 或者 0 占位。

例如:向 departments 表中添加一条数据,部门名称为 teaching ,工作地点 ID 为 4 。使用 0 占 位。

insert into departments values(0,"teaching",4);

5.2默认值处理(DEFAULT) 

在 MySQL 中可以使用 DEFAULT 为列设定一个默认值。如果在插入数据时并未指定该列的值,那么 MySQL 会将默认值添加到该列中。

5.2.1创建表时指定列的默认值

CREATE TABLE 表名(列名 类型 default 默认值,......);

示例:

创建 emp3 表,该表包含 emp_id 主键且自动增长,包含 name ,包含 address 该列默认 值为”未知”。

create table emp3(emp_id int primary key auto_increment,name varchar(10),address varchar(50) default 'Unknown');

5.2.2添加新列并指定默认值 

ALTER TABLE 表名 ADD COLUMN 列名 类型 DEFAULT 默认值;

示例:

修改 emp3 表,添加job_id 该列默认值为 0。

alter table emp3 add column job_id int default 0;

5.2.3插入数据时的默认值处理

如果在插入数据时并未指定该列的值,那么MySQL 会将默认值添加到该列中。如果是 完全项插入需要使用 default 来占位。

示例:

向 emp3 表中添加数据,要求 address 列与job_id 列使用默认值作为该列的值。

insert into emp3 values(default,"oldlu",default,default);

5.3更新数据(UPDATE)

UPDATE 表名 SET  列名=值,列名=值 WHERE 条件;

注意:


更新语句中一定要给定更新条件,否则表中的所有数据都会被更新。

示例:

更新 emp3 表中的 id 为 1 的数据,添加 address 为 BeiJing。

update emp3 set address = "BeiJing" where emp_id = 1;
delete from emp3 where emp_id = 1;

5.4删除数据(DELETE)

5.4.1DELETE删除数据

DELETE FROM  表名 WHERE 条件;

注意:

在DELETE语句中,如果没有给定删除条件则会删除表中的所有数据。

示例:

删除 emp3 表中 emp_id 为 1 的雇员信息。

delete from emp3 where emp_id = 1;

5.4.2TRUNCATE清空表

TRUNCATE TABLE  表名;

示例:

删除 emp3 表中的所有数据。

truncate table emp3;

5.4.3清空表时DELETE与 TRUNCATE 区别

  • truncate 是整体删除(速度较快), delete 是逐条删除(速度较慢);
  • truncate 不写服务器 log,delete 写服务器 log,也就是 truncate 效率比 delete 高的原因;
  • truncate 是会重置自增值,相当于自增列会被置为初始值,又重新从 1 开始记录,而 不是接着原来的值。而 delete 删除以后, 自增值仍然会继续累加。

六、MySQL中的DQL操作

6.1SELECT基本查询

6.1.1SELECT语句的功能

SELECT 语句从数据库中返回信息。使用一个 SELECT 语句,可以做下面的事:

  • 列选择:能够使用 SELECT 语句的列选择功能选择表中的列,这些列是想要用查询返回的。当查询时,能够返回列中的数据。

  • 行选择:能够使用 SELECT 语句的行选择功能选择表中的行,这些行是想要用查询返回的。能够使用不同的标准限制看见的行。

  • 连接:能够使用 SELECT 语句的连接功能来集合数据,这些数据被存储在不同的表中,在它们之间可以创建连接,查询出我们所关心的数据。


6.1.2SELECT基本语法

在最简单的形式中,SELECT 语句必须包含下面的内容:

  • 一个 SELECT 子句,指定被显示的列

  • 一个 FROM 子句,指定表,该表包含 SELECT 子句中的字段列表

语句含义
SELECT是一个或多个字段的列表
*选择所有的列
DISTINCT禁止重复
column | expression选择指定的字段或表达式
alias给所选择的列不同的标题
FROM table指定包含列的表

6.1.3选择所有列

select * from 表名;

示例:

查询 departments 表中的所有数据。

select * from departments;

6.1.4选择指定列

select 列名1,列名2,……  from 表名;

示例:

查询 departments 表中所有部门名称。

select department_name from departments;

6.1.5查询中的算术表达式

需要修改数据显示方式,如执行计算,或者作假定推测,这些都可能用到算术表达式。一个算术表达式可以包含列名、固定的数字值和算术运算符。

示例:

查询雇员的年薪,并显示他们的雇员ID,名字。

select employees_id,last_name, 12*salary from employees;

6.1.6运算符的优先级

6.1.7MySQL中定义空值

如果一行中的某个列缺少数据值,该值被置为 null, 或者说包含一个空。

空是一个难以获得的、未分配的、未知的,或不适用的值。空和 0 或者空格不相同。 0 是一个数字,而空格是一个字符。

6.1.8算数表达式中的空值                

6.1.9MySQL中的别名

SELECT  列名 AS  列别名 FROM  表名 WHERE  条件;

示例:

查询 employees 表为表定义别名为emp,将雇员 last_name 列定义别名为 name。

select emp.last_name name from employees emp;

6.1.10MySQL中去除重复

SELECT DISTINCT 列名 FROM 表名;

示例:

查询 employees 表,显示唯一的部门 ID。

select distinct department_id from employees;

6.1.11查询中的行选择

用 WHERE 子句限制从查询返回的行。一个 WHERE 子句包含一个必须满足的条件,WHERE 子句紧跟着 FROM 子句。如果条件是 true,返回满足条件的行。

SELECT * |  投影列 FROM  表名 WHERE  选择条件;

示例:

查询 departments 表中部门 ID 为 90 的部门名称与工作地点 ID。

select department_name,location_id from departments where department_id =4;

6.1.12MySQL中的比较条件

符号 != 也能够表示 不等于条件。

示例一:

查询 employees 表中员工薪水大于等于 3000 的员工的姓名与薪水。

select last_name,salary from employees where salary >= 3000;

6.1.13其他比较条件

使用BETWEEN条件(包含两侧)

可以用 BETWEEN 范围条件显示基于一个值范围的行。指定的范围包含一个下限和一个上限。

示例:

查询 employees 表,薪水在 3000-8000 之间的雇员ID、名字与薪水。

select employee_id,last_name,salary from employees where salary between 3000 and 8000;

使用IN条件

示例:

查询 employees 表,找出薪水是 5000,6000,8000 的雇员ID、名字与薪水。

select employee_id,last_name,salary from employees where salary in(5000,6000,8000);

使用LIKE条件

示例:

查询 employees 中雇员名字第二个字母是 e 的雇员名字。

select last_name from employees where last_name like '_e%';

使用NULL条件

NULL 条件,包括 IS NULL 条件和 IS NOT NULL 条件。

IS NULL 条件用于空值测试。空值的意思是难以获得的、未指定的、未知的或者不适用的。因此,你不能用 = ,因为 null 不能等于或不等于任何值。

示例一:

找出 emloyees 表中那些没有佣金的雇员雇员ID、名字与佣金。

select employee_id,last_name,commission_pct from employees where commission_pct is null;

6.1.14逻辑条件

逻辑条件组合两个比较条件的结果来产生一个基于这些条件的单个的结果,或者逆转一个单个条件的结果。当所有条件的结果为真时,返回行。

SQL 的三个逻辑运算符是:

  • AND
  • OR
  • NOT

可以在 WHERE 子句中用 AND 和 OR 运算符使用多个条件。

示例一:

查询 employees 表中雇员薪水是 8000 的并且名字中含有e 的雇员名字与薪水。

select last_name,salary from employees where salary = 8000 and last_name like '%e%';

6.1.15优先规则

6.1.16使用 ORDER BY 排序

在一个不明确的查询结果中排序返回的行。ORDER BY 子句用于排序。如果使用了 ORDER BY 子句,它必须位于 SQL 语句的最后。

SELECT 语句的执行顺序如下:

  • FROM 子句
  • WHERE 子句
  • SELECT 子句
  • ORDER BY 子句

示例一:

查询 employees 表中的所有雇员,显示他们的ID、名字与薪水,并按薪水升序排序。

select employee_id,last_name,salary from employees order by salary;
select employee_id,last_name,salary from employees order by salary asc;

使用别名排序

示例:

显示雇员ID,名字。计算雇员的年薪,年薪列别名为annsal,并对该列进行升序排序,

select employee_id,last_name ,12*salary annsal from employees order by annsal;

多列排序

示例:

以升叙排序显示 DEPARTMENT_ID 列,同时以降序排序显示 SALARY 列。

select department_id,salary from employees order by department_id asc ,salary desc;

6.1.17练习部分

1.创建一个查询,显示收入超过 12,000 的雇员的名字和薪水。

SELECT LAST_NAME ,SALARY FROM employees WHERE SALARY>12000;

2.创建一个查询,显示雇员号为 176 的雇员的名字和部门号。

select LAST_NAME,DEPARTMENT_ID from employees WHERE EMPLOYEE_ID = 176

3.显示所有薪水不在 5000 和 12000 之间的雇员的名字和薪水。

SELECT LAST_NAME ,SALARY from employees WHERE SALARY NOT BETWEEN 5000 AND 12000;

4.显示所有在部门 20 和 50 中的雇员的名字和部门号,并以名字按字母顺序排序。

SELECT LAST_NAME ,DEPARTMENT_ID from employees WHERE DEPARTMENT_ID IN
(20,50) ORDER BY LAST_NAME ASC;

5.列出收入在 5,000 和 12,000 之间,并且在部门 20 或50 工作的雇员的名字和薪水。将列标题分别显示为 Employee 和 Monthly Salary

SELECT LAST_NAME AS Employee,SALARY AS `Monthly Salary` FROM employees
WHERE SALARY BETWEEN 5000 AND 12000 AND DEPARTMENT_ID IN (20,50)

6.显示所有没有主管经理的雇员的名字和工作岗位。

SELECT LAST_NAME,JOB_ID FROM employees WHERE MANAGER_ID IS NULL;

7.显示所有有佣金的雇员的名字、薪水和佣金。以薪水和佣金的降序排序数据。

SELECT LAST_NAME,SALARY,COMMISSION_PCT*SALARY*12 FROM employees WHERE COMMISSION_PCT is not NULL ORDER BY SALARY DESC,COMMISSION_PCT DESC;

8.显示所有名字中有一个 a 和一个 e 的雇员的名字。

SELECT LAST_NAME FROM employees WHERE LAST_NAME LIKE '%a%e%' ;

9.显示所有工作岗位是销售代表(SA_REP)或者普通职员(ST_CLERK),并且薪水不等于 2,500、3,500 或 7,000 的雇员的名字、工作岗位和薪水。

SELECT LAST_NAME,JOB_ID,SALARY FROM employees WHERE JOB_ID IN ('SA_REP','ST_CLERK') AND SALARY NOT IN (2500,3500,7000);

七、MySQL函数

不同数据库对函数的实现时不同的,函数名也存在差异。

函数是 SQL 的一个非常强有力的特性,函数能够用于下面的目的:

  • 执行数据计算
  • 修改单个数据项
  • 操纵输出进行行分组
  • 格式化显示的日期和数字
  • 转换列数据类型

SQL 函数有输入参数,并且总有一个返回值。

7.1 单行函数

7.1.1单行函数的分类

单行函数仅对单个行进行运算,并且每行返回一个结果。

常见的函数类型:

  • 字符
  • 数字
  • 日期
  • 转换

 7.1.2字符函数

 大小写处理函数

函数描述实例
LOWER(s)|LCASE(s)将字符串 s 转换为小写

将字符串 JAVA 转换为小写:

SELECT LOWER("JAVA"); -- java

UPPER(s)|UCASE(s)将字符串s转换为大写

将字符串 java转换为大写:

SELECT UPPER("java"); -- JAVA

示例:

显示雇员 Davies 的雇员号、姓名和部门号,将姓名转换为大写。

SELECT EMPLOYEE_ID,UPPER(LAST_NAME),DEPARTMENT_ID FROM employees WHERE LAST_NAME = "Davies";

默认情况下MySQL中where子句的字符串是不区分大小写的 

字符处理函数

函数描述实例
length(s)返回字符串 s 的长度

返回字符串java的字符数

SELECT SELECT LENGTH("java");----4

concat(s1,s2...sn)字符串 s1,s2 等多个字符串合并为一个字符串

合并多个字符串

SELECT CONCAT("java", "MySQL ");-----javaMySQL 

lpad(s1,len,s2)在字符串 s1 的开始处填充字符串 s2,使字符串总长度达到 len

将字符串 "哈" 填充到 mysql字符串的开始处:

SELECT LPAD('mysql',8,'哈'); -- 哈哈哈mysql

ltrim(s)去掉字符串 s 开始处的空格

去掉字符串 Java开始处的空格:

SELECT LTRIM(" Java") ;-- Java

replace(s,s1,s2)将字符串 s2 替代字符串 s 中的字符串 s1

将字符串 java中的字符 a 替换为字符 O:

SELECT REPLACE('java','a','o'); --jovo

reverse(s)将字符串s的顺序反过来

将字符串 java的顺序反过来:

SELECT REVERSE('java');--avaj

rpad(s1,len,s2)在字符串 s1 的结尾处添加字符串 s2,使字符串的长度达到 len

将字符串 "哈"填充到 Java字符串的结尾处:

SELECT RPAD('Java',8,'哈'); ---Java哈哈哈哈

rtrim(s)去掉字符串 s 结尾处的空格

去掉字符串 java 的末尾空格:

SELECT RTRIM("java "); -- java

substr(s, start, length)从字符串 s 的 start 位置截取长度为 length 的子字符串

从字符串 Java中的第 2 个位置截取 3个 字符:

SELECT SUBSTR("Java", 2, 3); -- ava

substring(s, start, length)从字符串 s 的 start 位置截取长度为 length 的子字符串

从字符串 Java中的第 2 个位置截取 3个 字符:

SELECT SUBSTRING("Java", 2, 3); --ava

trim(s)去掉字符串 s 开始和结尾处的空格

去掉字符串 java的首尾空格:

SELECT TRIM(' java ');--java

instr(s1,s2)获取s2在s1首次出现的位置SELECT instr('java', 'a');--2

7.1.3数字函数

函数名描述实例
ABS(x)返回 x 的绝对值返回 -1 的绝对值:SELECT ABS(-1) -- 返回1
ACOS(x)求 x 的反余弦值(参数是弧度)SELECT ACOS(0.25);
ASIN(x)求反正弦值(参数是弧度)SELECT ASIN(0.25);
ATAN(x)求反正切值(参数是弧度)SELECT ATAN(2.5);
ATAN2(n, m)求反正切值(参数是弧度)SELECT ATAN2(-0.8, 2);
AVG(expression)返回一个表达式的平均值,expression 是一个字段返回 Products 表中Price 字段的平均值:SELECT AVG(Price) AS AveragePrice FROM Products;
CEIL(x)返回大于或等于 x 的最小整数SELECT CEIL(1.5) -- 返回2
CEILING(x)返回大于或等于 x 的最小整数SELECT CEILING(1.5); -- 返回2
COS(x)求余弦值(参数是弧度)SELECT COS(2);
COT(x)求余切值(参数是弧度)SELECT COT(6);
COUNT(expression)返回查询的记录总数,expression 参数是一个字段或者 * 号返回 Products 表中 products 字段总共有多少条记录:SELECT COUNT(ProductID) AS NumberOfProducts FROM Products;
DEGREES(x)将弧度转换为角度SELECT DEGREES(3.1415926535898) -- 180
n DIV m整除,n 为被除数,m 为除数计算 10 除于 5:SELECT 10 DIV 5; -- 2
EXP(x)返回 e 的 x 次方计算 e 的三次方:SELECT EXP(3) -- 20.085536923188
FLOOR(x)返回小于或等于 x 的最大整数小于或等于 1.5 的整数:SELECT FLOOR(1.5) -- 返回1
GREATEST(expr1, expr2, expr3, ...)返回列表中的最大值返回以下数字列表中的最大值:SELECT GREATEST(3, 12, 34, 8, 25); -- 34返回以下字符串列表中的最大值:SELECT GREATEST("Google", "Runoob", "Apple"); -- Runoob
LEAST(expr1, expr2, expr3, ...)返回列表中的最小值返回以下数字列表中的最小值:SELECT LEAST(3, 12, 34, 8, 25); -- 3返回以下字符串列表中的最小值:SELECT LEAST("Google", "Runoob", "Apple"); -- Apple
LN返回数字的自然对数,以 e 为底。返回 2 的自然对数:SELECT LN(2); -- 0.6931471805599453
LOG(x) 或 LOG(base, x)返回自然对数(以 e 为底的对数),如果带有 base 参数,则 base 为指定带底数。SELECT LOG(20.085536923188) -- 3 SELECT LOG(2, 4); -- 2
LOG10(x)返回以 10 为底的对数SELECT LOG10(100) -- 2
LOG2(x)返回以 2 为底的对数返回以 2 为底 6 的对数:SELECT LOG2(6); -- 2.584962500721156
MAX(expression)返回字段 expression 中的最大值返回数据表 Products 中字段 Price 的最大值:SELECT MAX(Price) AS LargestPrice FROM Products;
MIN(expression)返回字段 expression 中的最小值返回数据表 Products 中字段 Price 的最小值:SELECT MIN(Price) AS MinPrice FROM Products;
MOD(x,y)返回 x 除以 y 以后的余数5 除于 2 的余数:SELECT MOD(5,2) -- 1
PI()返回圆周率(3.141593)SELECT PI() --3.141593
POW(x,y)返回 x 的 y 次方2 的 3 次方:SELECT POW(2,3) -- 8
POWER(x,y)返回 x 的 y 次方2 的 3 次方:SELECT POWER(2,3) -- 8
RADIANS(x)将角度转换为弧度180 度转换为弧度:SELECT RADIANS(180) -- 3.1415926535898
RAND()返回 0 到 1 的随机数SELECT RAND() --0.93099315644334
ROUND(x)返回离 x 最近的整数SELECT ROUND(1.23456) --1
SIGN(x)返回 x 的符号,x 是负数、0、正数分别返回 -1、0 和 1SELECT SIGN(-10) -- (-1)
SIN(x)求正弦值(参数是弧度)SELECT SIN(RADIANS(30)) -- 0.5
SQRT(x)返回x的平方根25 的平方根:SELECT SQRT(25) -- 5
SUM(expression)返回指定字段的总和计算 OrderDetails 表中字段 Quantity 的总和:SELECT SUM(Quantity) AS TotalItemsOrdered FROM OrderDetails;
TAN(x)求正切值(参数是弧度)SELECT TAN(1.75); -- -5.52037992250933
TRUNCATE(x,y)返回数值 x 保留到小数点后 y 位的值(与 ROUND 最大的区别是不会进行四舍五入)SELECT TRUNCATE(1.23456,3) -- 1.234

ROUND(column|expressionn函数

ROUND 函数四舍五入列、表达式或者 n 位小数的值。如果第二个参数是 0 或者缺少,值被四舍五入为整数。如果第二个参数是 2值被四舍五入为两位小数。如果第二个参数是–2,值被四舍五入到小数点左边两位。

SELECT ROUND(45.923,2), ROUND(45.923,0),ROUND(45.923,-1);-----45.92,46,50

TRUNCATE(column|expression,n) 函数

TRUNCATE函数的作用类似于 ROUND 函数。如果第二个参数是 0 或者缺少,值被截断为整数。如果第二个参数是 2,值被截断为两位小数。如果第二个参数是–2,值被截断到小数点左边两位。与 ROUND 最大的区别是不会进行四舍五入。

SELECT TRUNCATE(45.923,2);--45.92

使用MOD(m,n) 函数

MOD 函数找出m 除以n的余数。

7.1.4日期函数

在MySQL中允许直接使用字符串表示日期,但是要求字符串的日期格式必须为:‘YYYY-MM-DD HH:MI:SS’ 或者‘YYYY/MM/DD HH:MI:SS’;

函数名描述实例
CURDATE()返回当前日期SELECT CURDATE(); -> 2018-09-19
CURTIME()返回当前时间SELECT CURTIME(); -> 19:59:02
CURRENT_DATE()返回当前日期SELECT CURRENT_DATE(); -> 2018-09-19
CURRENT_TIME()返回当前时间SELECT CURRENT_TIME(); -> 19:59:02
DATE()从日期或日期时间表达式中提取日期值SELECT DATE("2017-06-15"); -> 2017-06-15
DATEDIFF(d1,d2)计算日期 d1->d2 之间相隔的天数SELECT DATEDIFF('2001-01-01','2001-02-02') -> -32
DAY(d)返回日期值 d 的日期部分SELECT DAY("2017-06-15"); -> 15
DAYNAME(d)返回日期 d 是星期几,如 Monday,TuesdaySELECT DAYNAME('2011-11-11 11:11:11') ->Friday
DAYOFMONTH(d)计算日期 d 是本月的第几天SELECT DAYOFMONTH('2011-11-11 11:11:11') ->11
DAYOFWEEK(d)日期 d 今天是星期几,1 星期日,2 星期一,以此类推SELECT DAYOFWEEK('2011-11-11 11:11:11') ->6
DAYOFYEAR(d)计算日期 d 是本年的第几天SELECT DAYOFYEAR('2011-11-11 11:11:11') ->315
HOUR(t)返回 t 中的小时值SELECT HOUR('1:2:3') -> 1
LAST_DAY(d)返回给给定日期的那一月份的最后一天SELECT LAST_DAY("2017-06-20"); -> 2017-06-30
MONTHNAME(d)返回日期当中的月份名称,如 NovemberSELECT MONTHNAME('2011-11-11 11:11:11') -> November
MONTH(d)返回日期d中的月份值,1 到 12SELECT MONTH('2011-11-11 11:11:11') ->11
NOW()返回当前日期和时间SELECT NOW() -> 2018-09-19 20:57:43
SECOND(t)返回 t 中的秒钟值SELECT SECOND('1:2:3') -> 3
SYSDATE()返回当前日期和时间SELECT SYSDATE() -> 2018-09-19 20:57:43
TIMEDIFF(time1, time2)计算时间差值SELECT TIMEDIFF("13:10:11", "13:10:10"); -> 00:00:01
TO_DAYS(d)计算日期 d 距离 0000 年 1 月 1 日的天数SELECT TO_DAYS('0001-01-01 01:01:01') -> 366
WEEK(d)计算日期 d 是本年的第几个星期,范围是 0 到 53SELECT WEEK('2011-11-11 11:11:11') -> 45
WEEKDAY(d)日期 d 是星期几,0 表示星期一,1 表示星期二SELECT WEEKDAY("2017-06-15"); -> 3
WEEKOFYEAR(d)计算日期 d 是本年的第几个星期,范围是 0 到 53SELECT WEEKOFYEAR('2011-11-11 11:11:11') -> 45
YEAR(d)返回年份SELECT YEAR("2017-06-15"); -> 2017

7.1.5转换函数

隐式数据类型转换

隐式数据类型转换是指MySQL服务器能够自动地进行类型转换。如:可以将标准格式的字串日期自动转换为日期类型。

MySQL字符串日期格式为:‘YYYY-MM-DD HH:MI:SS’ 或 ‘YYYY/MM/DD HH:MI:SS’;

显示数据类型转换

显示数据类型转换是指需要依赖转换函数来完成相关类型的转换。

如:

  • DATE_FORMAT(date,format) 将日期转换成字符串;

  • STR_TO_DATE(str,format) 将字符串转换成日期;

示例一:

向 employees 表中添加一条数据,雇员ID:400,名字:张三,email:zhangsan@qq.cn ,入职时间:2049 年 5 月 5 日,工作部门:‘IT_PROG’。

insert into employees(EMPLOYEE_ID,last_name,email,HIRE_DATE,JOB_ID) values(400,'zhangsan','zhangsanqq.cn', STR_TO_DATE('2049 年 5 月 5 日','%Y 年%m 月%d 日'),'IT_PROG');

示例二:

查询 employees 表中雇员名字为 King 的雇员的入职日期,要求显示格式为 yyyy 年 MM 月 dd 日。

select DATE_FORMAT(hire_date,'%Y 年%m 月%d 日') from employees where last_name = 'King';

7.1.6通用函数

函数名描述实例
IF(expr,v1,v2)如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。SELECT IF(1 > 0,'正确','错误') ->正确
IFNULL(v1,v2)如果 v1 的值不为 NULL,则返回 v1,否则返回 v2。SELECT IFNULL(null,'Hello Word') ->Hello Word
ISNULL(expression)判断表达式是否为 NULLSELECT ISNULL(NULL); ->1
NULLIF(expr1, expr2)比较两个参数是否相同,如果参数 expr1 与 expr2 相等 返回 NULL,否则返回 expr1SELECT NULLIF(25, 25); ->null
COALESCE(     expr1   , expr2, ...., expr_n)返回参数中的第一个非空表达式(从左向右)SELECT COALESCE(NULL, NULL, NULL, 'bjsxt.com', NULL, 'google.com'); -> bjsxt.com
CASE expression WHEN condition1 THEN result1 WHEN condition2 THEN result2 ... WHEN conditionN THEN resultN ELSE result ENDCASE 表示函数开始,END 表示函数结束。如果 condition1 成立,则返回 result1, 如果 condition2 成立,则返回 result2,当全部不成立则返回 result,而当有一个成立之后,后面的就不执行了。SELECT CASE 'oldlu' WHEN 'oldlu' THEN 'OLDLU' WHEN 'admin' THEN 'ADMIN' ELSE 'kevin' END;

示例一:

查询部门编号是50或者80的员工信息,包含他们的名字、薪水、佣金。在income列中,如果有佣金则显示‘SAL+COMM’,无佣金则显示'SAL'。

SELECT last_name, salary, commission_pct,     
if(ISNULL(commission_pct),'SAL','SAL+COMM') income 
FROM employees 
WHERE department_id IN (50, 80);

示例二:

计算雇员的年报酬,你需要用 12 乘以月薪,再加上它的佣金 (等于年薪乘以佣金

SELECT last_name, salary, IFNULL(commission_pct, 0), (salary*12) +(salary*12*IFNULL(commission_pct, 0)) AN_SAL 
FROM employees;

示例三

查询员工表,显示他们的名字、名字的长度该列名为expr1,姓氏、姓氏的长度该列名为expr2。在result列中,如果名字与姓氏的长度相同则显示空,如果不相同则显示名字长度。

SELECT first_name, LENGTH(first_name) "expr1",last_name, LENGTH(last_name) "expr2",     
   NULLIF(LENGTH(first_name), LENGTH(last_name)) result
FROM employees;

示例四:

查询员工表,显示他们的名字,如果 COMMISSION_PCT 值是非空,显示它。如果COMMISSION_PCT 值是空,则显示 SALARY 。如果 COMMISSION_PCT 和SALARY 值都是空,那么显示 10。在结果中对佣金列升序排序。

SELECT last_name,
COALESCE(commission_pct, salary, 10) comm 
FROM employees 
ORDER BY commission_pct;

示例五:

查询员工表,如果 JOB_ID 是 IT_PROG,薪水增加 10%;如果 JOB_ID 是 ST_CLERK,薪水增加 15%;如果 JOB_ID 是 SA_REP,薪水增加 20%。对于所有其他的工作角色,不增加薪水。

SELECT last_name, job_id, salary, 
    CASE job_id WHEN 'IT_PROG' THEN 1.10*salary 
          WHEN 'ST_CLERK' THEN 1.15*salary 
          WHEN 'SA_REP' THEN 1.20*salary 
    ELSE salary END "REVISED_SALARY"
FROM employees;

7.1.7单行函数练习

1.显示受雇日期在 1998 年 2 月 20 日 和 2005 年 5 月 1 日 之间的雇员的名字、岗位和受雇日期。按受雇日期顺序排序查询结果。

select LAST_NAME,JOB_ID,HIRE_DATE 
FROM employees 
WHERE  HIRE_DATE BETWEEN '1998-02-20' AND '2005-05-01' 
ORDER BY HIRE_DATE;

2.显示每一个在 2002 年受雇的雇员的名字和受雇日期。

select LAST_NAME,HIRE_DATE 
FROM employees 
WHERE  YEAR(HIRE_DATE) = 2002;

或者

select LAST_NAME,HIRE_DATE 
FROM employees 
WHERE  HIRE_DATE LIKE '2002%';

3.对每一个雇员,显示 employee number、last_name、salary 和 salary 增加 15%,并且表示成整数,列标签显示为 New Salary。

SELECT EMPLOYEE_ID 'employee number',LAST_NAME,SALARY,ROUND(1.15*SALARY) 'New Salary'
FROM employees;

4.写一个查询,显示名字的长度,对所有名字开始字母是 J、A 或 M 的雇员。用雇员的 lastname排序结果。

SELECT LAST_NAME, LENGTH(LAST_NAME)
FROM employees
WHERE SUBSTR(LAST_NAME,1,1) IN ('J','A','M')
ORDER BY LAST_NAME;

5.创建一个查询显示所有雇员的 last name 和 salary。将薪水格式化为 15 个字符长度,用 $左填充 。

SELECT LAST_NAME, LPAD(SALARY,15,'$')
FROM employees;

6.创建一个查询显示雇员的 last names 和 commission (佣金) 比率。如果雇员没有佣金,显示 “No Commission”,列标签 COMM。

SELECT LAST_NAME, IFNULL(COMMISSION_PCT,'No Commission') COMM
FROM employees;

 7.写一个查询,按照下面的数据显示所有雇员的基于 JOB_ID 列值的级别。

工作级别
AD_PRESA
ST_MANB
IT_PROGC
SA_REPD
ST_CLERKE
不在上面的0
SELECT JOB_ID,
CASE JOB_ID
       WHEN 'AD_PRES' THEN  'A' 
         WHEN 'ST_MAN' THEN  'B' 
         WHEN 'IT_PROG' THEN  'C'
         WHEN 'SA_REP' THEN  'D'
         WHEN 'ST_CLERK' THEN  'E'
    ELSE
        0
END
FROM employees;

7.2多行函数 (聚合函数) 

聚合函数也称之为多行函数,组函数或分组函数。聚合函数不象单行函数,聚合函数对行的分组进行操作,对每组给出一个结果。如果在查询中没有指定分组,那么聚合函数则将查询到的结果集视为一组。

7.2.1聚合函数的类型

函数名描述实例
AVG(expression)返回一个表达式的平均值,expression 是一个字段返回 Products 表中Price 字段的平均值:SELECT AVG(Price) AS AveragePrice FROM Products;
COUNT(expression)返回查询的记录总数,expression 参数是一个字段或者 * 号返回 Products 表中 products 字段总共有多少条记录:SELECT COUNT(ProductID) AS NumberOfProducts FROM Products;
MAX(expression)返回字段 expression 中的最大值返回数据表 Products 中字段 Price 的最大值:SELECT MAX(Price) AS LargestPrice FROM Products;
MIN(expression)返回字段 expression 中的最小值返回数据表 Products 中字段 Price 的最小值:SELECT MIN(Price) AS MinPrice FROM Products;
SUM(expression)返回指定字段的总和计算 OrderDetails 表中字段 Quantity 的总和:SELECT SUM(Quantity) AS TotalItemsOrdered FROM OrderDetails;

7.2.2聚合函数使用方式

7.2.3聚合函数的使用原则

  • DISTINCT 使得函数只考虑不重复的值;
  • 所有聚合函数忽略空值。为了用一个值代替空值,用 IFNULL 或 COALESCE 函数。

7.2.4AVG 和 SUM 函数

    AVG(arg)函数

     对分组数据做平均值运算。

     arg:参数类型只能是数字类型。

   SUM(arg)函数

     对分组数据求和。

    arg:参数类型只能是数字类型。

示例:

计算员工表中工作编号含有REP的工作岗位的平均薪水与薪水总和。

SELECT AVG(salary),SUM(salary)
FROM employees
WHERE job_id LIKE '%REP%';

7.2.5MIN 和 MAX 函数

MIN(arg)函数

求分组中最小数据。

arg:参数类型可以是字符、数字、 日期。

MAX(arg)函数

求分组中最大数据。

arg:参数类型可以是字符、数字、 日期。

示例:

查询员工表中入职时间最短与最长的员工,并显示他们的入职时间。

SELECT MIN(hire_date), MAX(hire_date) FROM employees;

7.2.6count函数

返回分组中的总行数。

COUNT 函数有三种格式:

  • COUNT(*):返回表中满足 SELECT 语句的所有列的行数,包括重复行,包括有空值列的行。

  • COUNT(expr):返回在列中的由 expr 指定的非空值的数。

  • COUNT(DISTINCT expr):返回在列中的由 expr 指定的唯一的非空值的数。

使用 DISTINCT 关键字

  • COUNT(DISTINCT expr) 返回对于表达式 expr 非空并且值不相同的行数

  • 显示 EMPLOYEES 表中不同部门数的值

示例一:

显示员工表中部门编号是80中有佣金的雇员人数。

SELECT COUNT(commission_pct) FROM employees WHERE department_id = 80;

7.2.7数据分组

在没有进行数据分组之前,所有聚合函数是将结果集作为一个大的信息组进行处理。但是,有时,则需要将表的信息划分为较小的组,可以用 GROUP BY 子句实现。

GROUP BY 子句语法

原则

  • 使用 WHERE 子句,可以在划分行成组以前过滤行。
  • 如果有WHERE子句,那么GROUP BY 子句必须在WHERE的子句后面。
  • 在 GROUP BY 子句中必须包含列。

使用 GROUP BY 子句

下面是包含一个 GROUP BY 子句 SELECT 语句的求值过程:

  • SELECT 子句指定要返回的列:

  • 在 EMPLOYEES 表中的部门号

    − GROUP BY 子句中指定分组的所有薪水的平均值

    − FROM 子句指定数据库必须访问的表:EMPLOYEES 表。

  • WHERE 子句指定被返回的行。因为无 WHERE 子句默认情况下所有行被返回。

  • GROUP BY 子句指定行怎样被分组。行用部门号分组,所以 AVG 函数被应用于薪水列,以计算每个部门的平均薪水。

示例:

计算每个部门的员工总数。

SELECT DEPARTMENT_ID, COUNT(*) FROM employees GROUP BY DEPARTMENT_ID;

八、多表查询

多表查询分类

  • sql92标准:内连接(等值连接 、非等值连接 、 自连接)。
  • sql99标准:内连接、外连接(左外、右外、全外(MySQL不支持全外连接))、交叉连接。

8.1 SQL92标准中的查询

8.1.1等值连接

等值连接

为了确定一个雇员的部门名,需要比较 EMPLOYEES 表中的 DEPARTMENT_ID 列与DEPARTMENTS 表中的 DEPARTMENT_ID 列的值。在 EMPLOYEES 和DEPARTMENTS 表之间的关系是一个相等 (equijoin) 关系,即,两 个 表 中DEPARTMENT_ID 列的值必须相等。

等值连接特点:

  1. 多表等值连接的结果为多表的交集部分;
  2. n表连接,至少需要n-1个连接条件;
  3. 多表不分主次,没有顺序要求;
  4. 一般为表起别名,提高阅读性和性能;
  5. 可以搭配排序、分组、筛选….等子句使用;

注意:

等值连接也被称为简单连接 (simple joins) 或内连接 (inner joins)。

等值连接的使用

增加搜索条件

使用表别名

表别名定义原则

  • 表别名不易过长,短一些更好。
  • 表别名应该是有意义的。
  • 表别名只对当前的 SELECT 语句有效。

多表连接 

示例一:

查询雇员 King 所在的部门名称。

select d.department_name 
from employees e,departments d  
where e.dept_id = d.department_id and e.last_name = 'King';

示例二:

显示每个雇员的 last name、departmentname 和 city。

SELECT e.last_name, d.department_name, l.city 
FROM employees e, departments d, locations l 
WHERE e.department_id = d.department_id 
AND d.location_id = l.location_id;

8.1.2非等值连接

示例三:

查询所有雇员的薪水级别。

select e.last_name,j.grade_level 
from employees e ,job_grades j 
where e.salary between j.lowest_sal and j.highest_sal;

8.1.3自连接

自连接

连接一个表到它自己。有时需要连接一个表到它自己。为了找到每个雇员的经理的名字,则需要连接EMPLOYEES 表到它自己,或执行一个自连接。

图片中的例子连接 EMPLOYEES 表到它自己。为了在 FROM 子句中模拟两个表,对于相同的表 EMPLOYEES,用两个别名,分别为 worker 和 manager。在该例中,WHERE 子句包含的连接意味着 “一个工人的经理号匹配该经理的雇员号”。

示例一:

查询每个雇员的经理的名字以及雇员的名字,雇员名字列别名为W,经理列别名为M。

SELECT
worker.LAST_NAME W,manager.LAST_NAME M
from employees worker,employees manager
where worker.MANAGER_ID = manager.EMPLOYEE_ID;

示例二:

查询Fox的经理是谁?显示他的名字。

SELECT
worker.LAST_NAME,manager.LAST_NAME
from employees worker,employees manager
where worker.MANAGER_ID = manager.EMPLOYEE_ID
AND worker.LAST_NAME = 'Fox';

8.2SQL99标准中的查询

8.2.1交叉连接

8.2.2自然连接

自然连接

连接只能发生在两个表中有相同名字和数据类型的列上。如果列有相同的名字,但数据类型不同,NATURAL JOIN 语法会引起错误。

自然连接也可以被写为等值连接:

SELECT d.department_id, d.department_name,
d.location_id , l.city
FROM departments d , locations l
WHERE d.location_id = l.location_id;

8.2.3内连接

示例:

查询雇员名字为 Fox 的雇员 ID ,薪水与部门名称。

select e.employee_id,e.salary,d.department_name 
from employees e inner JOIN departments d on e.department_id = d.department_id 
where e.last_name = 'Fox';

8.2.4左外连接和右外连接

示例:

查询所有雇员的名字以及他们的部门名称,包含那些没有部门的雇员。

select e.last_name,d.department_name 
from employees e LEFT OUTER JOIN departments d 
on e.dept_id = d.department_id;

示例:

查询所有雇员的名字以及他们的部门名称,包含那些没有雇员的部门。

select  e.last_name,d.department_name 
from  employees  e RIGHT OUTER JOIN  departments  d 
on e.DEPARTMENT_ID = d.department_id;

8.2.5多表连接查询练习

1.写一个查询显示所有雇员的 last name、department id、and department name。

select e.LAST_NAME,e.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM employees e,departments d
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID;

2.写一个查询显示所有有佣金的雇员的 last name、department name、location ID 和城

select e.LAST_NAME,d.DEPARTMENT_NAME,l.LOCATION_ID,l.CITY
FROM  employees e,departments d,locations l
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND d.LOCATION_ID = l.LOCATION_ID
AND e.COMMISSION_PCT IS NOT NULL;

3.显示所有在其 last names 中有一个小写 a 的雇员的 last name 和 department name。

SELECT e.LAST_NAME,d.DEPARTMENT_NAME
FROM employees e,departments d
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.LAST_NAME like '%a%'

4.用sql99的内连接写一个查询显示那些工作在 Toronto 的所有雇员的 last name、job、department number 和 department name。

SELECT e.LAST_NAME,e.JOB_ID,e.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM employees e INNER JOIN departments d 
ON e.DEPARTMENT_ID = d.DEPARTMENT_ID INNER JOIN locations l
ON d.LOCATION_ID = l.LOCATION_ID
WHERE l.CITY = 'Toronto';

6.显示雇员的 last name 和 employee number 连同他们的经理的 last name 和manager number。列标签分别为 Employee、Emp#、Manager 和 Mgr#

SELECT w.LAST_NAME empname,w.DEPARTMENT_ID empid,m.LAST_NAME mgrname,m.EMPLOYEE_ID mgrid
FROM employees w INNER JOIN employees m
ON w.MANAGER_ID = m.EMPLOYEE_ID;

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张小猿ε٩(๑> ₃ <)۶ з

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值