MySql基础

一:为什么要学习数据库:
    之前的操作会将数据存储在文档中,对于修改删除等操作来说,比较繁琐查询效率也较低,
    另外,数据量很大的情况下,不肯能长期储存在稳健中,而数据库是按照数据机构来组织、
    存储和管理数据的仓库,能为多个用户提供共享,各程序之间彼此独立的数据集合,
    简单来说可以看成数据仓库,用户可以对文件中的数据进行新增,截取,更新,删除等操作。
二:数据库的相关概念
    DBMS:数据库管理系统(mysql,orcal,sqlserver...)
    DB:database,数据库
    SQL:structure query language结构化查询语言
三:数据库存储数据的特点:
    1.将数据存放在表中,表放在库里
    2.一个数据库中可以有非常多的表,每个表都有名字用来标识自己,表名具有唯一性
    3.表具有自己的特性,这些特性定义了数据在表中的方式以及结构
    4.表由列组成,称为字段,所有表是由一个或多个字段组成的
    5.表中的数据按行存储
四:初始mysql
   1.mysql产品介绍
     关系型数据库:包括相互联系的数据集合,将所有数据关系以数据库表的形式加以表示并将数据存储在表格中
                  体积小,速度快,总体拥有成本低,开源的(发展会比较稳健,免费)
   2.mysql产品的安装
     服务端:处理具体数据的维护,保存磁盘
     客户端:执行新增,删除,修改,查询
            DOS窗口是数据库的客户端之一
            windows+r 输入cmd 输入mysql -uroot -proot 回车
作业:安装mysql数据库,成功打开dos窗口
   3.MySQL服务的登录和退出:
     登录:mysql -uroot -proot
     退出:exit/quite;
   4.MySQL服务器的启动和停止:
     启动:net start MySQL
     停止:net stop MySQL
   5.MySQL的常见命令和语法规范:
     SQL:结构化查询语言,是一种特殊的编程语言,用来存储以及查询更新和管理数据库系统
     分类:
        DDL:数据定义语言,用来定义数据库对象(库/表/列),负责数据结构定义
            常用create\alter\drop
        DML:数据操作语言,用来定义数据库记录(数据),数据增删改的操作
            常用select\insert\update\delete
        DCL:数据控制语言,用来定义访问权限和安全级别
            访问权限grant或者revoke取消授权
        DQL:数据查询语言,用来查询记录(数据)
            select数据检索语句
命令:1.创建数据库:create database 库名 character set utf8;
     2.展示数据库:show databases;
     3.选择使用数据库:use 数据库名;
     4.展示数据库里的所有表:show tables;     
     5.创建了一个表:字段,字段的数据类型
        create table stu(
           -> stuno int(6),-------->(字段名1 数据类型(字段约束条件),)
           -> name varchar(8),
           -> score varchar(5)
           -> );
     6.查询表结构desc stu;
     7.插入语句:insert into emp values(001,'30000','Lisa');
     8.数据检索语句:select * from emp(表名);
     9.查看数据库编码:show variables like 'char%';
     10.查看数据库版本:select version();
     11.删除表(一个或多个):DROP TABLE stu;   DROP TABLE [IF EXISTS] stu,emp;
   6.Mysql中的数据类型:
      数值类型:
            int普通整数(4字节),double双精度浮点数(8字节),decimal严格的定点数值
      字符型类型:
            varchar可变长度字符串,char固定长度字符串,enum枚举类型(1或2个字节)
      时间\日期类型:
            year年YYYY    date年月日YYYY-MM-DD    Time时分秒HH:MM:SS
            datatime8字节(可以存入一个固定时间,YYYY-MM-DD HH:MM:SS)
            timestamp4字节(本身存储的数据是从1970-1-1----2038的所有时间数据,可以自动更新当前时间)
   7.完整性约束:
     1.主键约束:
        表中由一列或者多列的组合,要求主键字段数据的唯一性,并且不能为空
          单字段约束:
         (1)在定义某一字段的同时定义主键
              字段名 数据类型(字段约束条件) primary key;
         (2)在定义完字段后定义主键:
              primary key(字段名);
          多字段约束:
              primary key(字段名1,字段名2...)
     2.主键自增约束:
        每次插入新的信息时,系统会自动递增生成字段的主键值
        在一个表上自动递增的数据只有一个
            字段名 数据类型(字段约束条件) primary key auto_increment;
     3.外键约束
        外键就是在不同的表之间建立连接,一个表可以有一个或多个外键
        外键不一定是本表的主键,但对应的是另外一个表的主键
        与外键关联的字段不允许被删除,如果必须删除首先要将外键撤销
        foreing key(字段名) reference 主表名(主键字段);
     4.非空约束:
        字段值不能为空
            字段名 数据类型 not null;
     5.唯一性约束:
        对某字段使用此约束,允许为空,但是只出现一个空值
            字段名 数据类型 unique;
作业:1.新建课程表course,插入三个字段:cno\cname\tno
     2.新建成绩表score,插入三个字段:sno\cno\tno\degree
       主键:sno+cno
五:DQL语言的学习:select
   1.基础查询
     (1)查询所有表信息
        select * from studen
     (2)查询相关字段信息
        SELECT sname,ssex,class(字段1,2,3...)FROM student;
     特点:通过这样的查询可以查询到表中所有字段,常量,函数,表达式
          结果是一个虚拟表格
     (3)查询常量值:SELECT 10985(常量值)
     (4)查询表达式:SELECT 100%98(表达式);
        注意事项:SELECT 100+98;操作都是数值类型的话做加法运算
                SELECT '123'+98;其中一个数是字符串类型,字符串转换成功则做加法运算;
                                字符串转换不成功则转换成0继续做加法运算
                SELECT NULL+10;只要其中一个加号是null,则结果肯定是null
     (5)去重查询:查询某字段中去除重复信息后数据(DISTINCT)
        SELECT DISTINCT class FROM student;
   2.条件查询
        语法:SELECT 查询列表(字段) FROM 表名 WHERE 筛选条件;
        条件判断符:
        =\>\<\!=\<=\>=
        逻辑运算符:
        &&与(两边为真为真,只要有一个为假,结果为假),||或(两边为假就为假,只要有一边为真结果就为真),  !非
        AND 并且
        OR 或者
        not 相反
     (1)查询表中成绩在70-90之间所有数据
        SELECT * FROM score WHERE degree BETWEEN 70 AND 90;
     (2)查询score表成绩是85,92,90的数据
        SELECT * FROM score WHERE degree=85 OR degree=92 OR degree=90;
        select * from score where degree in(85,92,95);
     (3)查询student表中性别为女以及班名为15038的所有数据
        SELECT * FROM student WHERE ssex='女' OR class='15038';
     (4)以degree降序(DESC)查询sccore表中的所有数据(升序为ASC)
        SELECT * FROM score ORDER BY degree DESC;
     (5)查询部门编号不等于90号的员工名和部门编号
        SELECT last_name department_id FROM employees WHERE department_id!=90;
     (6)查询工资在10000到2000之间的员工姓名、工资以及奖金
        SELECT first_name,salary,commission_pct FROM employees WHERE salary>=10000 AND salary <=20000;
     (7)查询部门编号不是90到110之间的,或者工资高于15000的员工信息
        SELECT * FROM employees WHERE NOT (department_id >= 90 AND department_id <= 110) OR salary >= 15000;
   3.模糊查询    
    3.1 like
        特点:一般情况下和通配符搭配使用
             %任意多个字符,包含0个字符
             _任意单个字符
     (1)查询员工姓名中包含字符a的员工信息
        SELECT * FROM employees WHERE last_name LIKE '%a%';
     (2)查询员工名中第三个字符为e,第五个字符为a的员工名和工资
        SELECT last_name,salary FROM employees WHERE last_name LIKE '__e_a%';
     (3)查询员工名中第二个字符为_的员工名(ESCAPE转义名词,用下划线表示一个字符的通配符,如果需要查询某个字段中的记录,我们需要定义一个带字符,使用完毕后escape排除这个字符,也就是自定义将$转义成_)
        SELECT last_name FROM employees WHERE last_name LIKE '_$_%' ESCAPE '$';
    3.2 BETWEEN...AND...位于两值之间
        特点:1.提高语句的简洁度
             2.包含临界值
             3.这两个临界值不能调换位置
    3.3 IN(set)包含,判断某个字段的值是否属于In列表中的某一项
        特点:1.提高语句简洁度
             2.in列表的数据类型必须一致
             3.in列表的值不支持通配符
     (1)查询job_id是IT_PROG、AD_PRES的员工姓名和job_id
        SELECT job_id,last_name FROM employees WHERE job_id IN('IT_PROG',' AD_PRES');
     (2)查询employee_id是100,102,103的员工
        SELECT * FROM employees WHERE employee_id in(100,102,103);
    3.4 is null 为空is not null 不为空
        注意:=和<>都不能判断判断NULL
     (1)查询commission_pct为空的员工名字和commission_pct
        SELECT commission_pct,last_name FROM employees WHERE commission_pct IS NULL;
     (2)安全等于表达符号<=>
        查询没有奖金的员工名字和奖金
        SELECT commission_pct,last_name FROM employees WHERE commission_pct<=>NULL;
    3.5 起别名:
        特点:1.便于理解
             2.如果需要使用的字段有重名的现象,使用别名就可以区分开来
               使用关键字AS或者空格
     (1)查询员工姓名,并将姓名重命名为'姓名'
        SELECT last_name AS 姓,first_name AS 名 FROM employees;
     (2)查询salary,显示结果为‘output’
        SELECT salary AS 'output' FROM employees;
   4.排序查询:
        语法:SELECT * FROM 表名 ORDER BY 排序的字段或者表达式 DESC;
        特点:1.DESC表示降序,ASC表示升序
             2.oeder by是可以支持单个字段、别名、表达式、函数
             3.写在查询语句的最后,除了limit字句
     (1)查询员工信息并且按照工资从高到低排列
        SELECT * FROM employees ORDER BY salary DESC;
     (2)查询部门编号>=90的员工信息并且按照员工编号降序
        SELECT * FROM employees WHERE department_id>=90 ORDER BY   employee_id DESC;
     (3)查询员工信息并且按照年薪降序排序
        SELECT * FROM employees ORDER BY salary*12*(1IFNULL(commission_pct,0)) DESC;
     (4)起别名(3)---表达式
        SELECT *,salary*12*(1+IFNULL(commission_pct,0))AS 年薪 FROM  employees ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
     (5)查询员工名,并且按照名字长度排序---函数
        SELECT LENGTH(last_name),last_name FROM employees ORDER BY   LENGTH(last_name) DESC;
     (6)查询员工信息,先按工资降序再按员工编号升序
        SELECT * FROM employees ORDER BY salary DESC,employee_id ASC;
     (7)查询员工的姓名和部门和年薪,按照年薪降序,再按照员工名升序
        SELECT
            department_id,
            last_name,
            salary * 12 * (1 + IFNULL(commission_pct, 0))
        FROM
            employees
        ORDER BY
            salary * 12 * (1 + IFNULL(commission_pct, 0)) DESC,
            last_name ASC;
     (8)查询邮箱中包含e的员工信息,先按邮箱的字节数降序,再按部门编号升序*/
        SELECT * FROM employees WHERE email LIKE '%e%' ORDER BY   LENGTH(email) DESC,department_id ASC;
   5.常见函数
        在java里面将一组逻辑语言封装在方法体中
        优点:1.隐藏代码运行细节
             2.提高代码的重用性
        在数据库中调用:select 函数名 (实参列表)
        特点:1.函数名
             2.函数功能
    5.1单行函数(一个函数返回一个值)
    字符函数:
        LENGTH\content\IFNULL...
     (1)LENGTH()获取参数值的字节个数
        SELECT LENGTH('Ellen');
     (2)CONCAT(,,)拼接字符串
        SELECT CONCAT(last_name,'_',first_name) AS 姓名 FROM employees;
     (3)UPPER(),LOWER()转换大小写
        SELECT UPPER('dwt');
        SELECT LOWER('DWT');
     (4)将员工表里的姓大写,名小写,然后拼接
        SELECT CONCAT(UPPER(last_name),LOWER(first_name)) AS 姓名 FROM   employees;
     (5)SUBSTR()截取数据
        SELECT SUBSTR('今晚我想吃大盘鸡',7) AS 结果;
        SELECT SUBSTR('今晚我想吃大盘鸡',5,4) AS 结果2;
     (6)姓名中首字符大写,其他字符小写然后用_拼接,显示为结果3
        SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_'
        LOWER(SUBSTR(Last_name,2))) AS 结果3 FROM employees;
     (7)instr()通过子串的下标索引获取
        SELECT INSTR('路飞一行人踏上了征程','征程') AS 结果;
     (8)TRIM()截取
        SELECT LENGTH(TRIM('   乔巴   ' ));/*6*/
        SELECT TRIM('a' FROM 'aaaaaa乌aaaa索普aaaaaaaaaaaaaa') AS 结果;/*乌aaaa索普*/
        SELECT TRIM('aa' FROM 'aaaaaaa乌aaaa索普aaaaaaaaaaaaaa')AS 结果2;/*乌aaaa索普*/
     (9)LPAD()用指定的字符去实现左填充指定长度
        SELECT LPAD('山治',10,'*');/*(********山治)*/
     (10)RPAD()用指定的字符去实现右填充指定长度
        SELECT RPAD('山治',10,'*');/*(山治********)*/
     (11)REPLACE()替换
        SELECT  REPLACE('我最近爱上了学习','爱上了','酷爱') AS 结果;/*我最近酷爱学习*/
        SELECT  REPLACE('我最近爱上了爱上了学习','爱上了','酷爱') AS 结果1;/*我最近酷爱酷爱学习*/
    数学函数:
     (1)ROUND()四舍五入  
        SELECT ROUND(1.55);/*2*/
        SELECT ROUND(-1.55);/*-2*/
     (2)CEIL()向上取整,返回值大于等于该参数的最小整数
        SELECT CEIL(0.01);/*1*/
        SELECT CEIL(-1.12);/*-1*/
     (3)FLOOR()向下取整,返回值小于等于该参数的最大整数
        SELECT FLOOR(9.99);/*9*/
        SELECT FLOOR(-9.99);/*-10*/
     (4)TRUNCATE()
        SELECT TRUNCATE(1.65,1);/*1.6*/
        SELECT TRUNCATE(1.699999,2);/*1.69*/
     (5)MOD()取余*/
        SELECT MOD(10,-3);/*1*/
        SELECT MOD(-10,3);/*-1*/
    日期函数:
     (1)NOW()当前日期+时间
        SELECT NOW();
     (2)CURDATE()当前日期
        SELECT CURDATE();
     (3)CURTIME()当前时间
        SELECT CURTIME();
     (4)获取指定年份
        SELECT YEAR('2020-05-05');
     (5)查询员工表里入职时间的所有年份*/
        SELECT YEAR(hiredate) AS 年份 FROM employees;
     (6)获取指定月份
        SELECT MONTH(NOW());
     (7)获取月份名称
        SELECT MONTHNAME(NOW());
     (8)STR_TO_DATE()将字符通过指定的格式转换成日期
        SELECT STR_TO_DATE('2000-12-8','%Y-%m-%d')AS 结果;
     (9)查询入职日期是1992-4-3的员工
        SELECT * FROM employees WHERE hiredate=STR_TO_DATE('1992-4-3','%Y-%m-%d');
     (10)DATE_FORMAT()将日期转换成字符*/
        SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') 结果;
     (11)查询有奖金的员工名和入职日期(xx年xx月xx日)*/
        SELECT last_name,DATE_FORMAT(hiredate,'%m月%d日%y年') FROM employees WHERE commission_pct IS NOT NULL;
    其他函数:
        SELECT VERSION();
        SELECT DATABASE();
        SELECT USER();
    流程控制函数
     (1)IF函数:if else 的效果
        SELECT IF('10>5','大','小');
        SELECT last_name,commission_pct,
        IF(commission_pct
        IS NULL,'没奖金','有奖金')
        FROM employees;
重点 (2)case函数:switch case函数
        switch(变量或者表达式){
         case1 常量1:语句1;break;
         case2
         ...
         default:语句 n;break;}
        mysql里:
         case要判断的字段或表达式
         when 常量1 then 要显示的值(语句1)
         when 常量2 then 要显示的值(语句2)
         ...
         end
        查询员工的工资,要求:
        部门号是10的,显示的工资是1.1倍
        部门号是40的,显示的工资是1.2倍
        部门号是70的,显示的工资是1.3倍
        其他的部门,显示的工资是原工资
        SELECT salary AS 原工资,department_id,
        CASE department_id
        WHEN 10 THEN 1.1*salary
        WHEN 40 THEN 1.2*salary
        WHEN 70 THEN 1.3*salary
        ELSE salary
        END AS 新的工资
        FROM employees;
难点 (3)查询员工的工资:
        如果工资大于20000,显示A
        如果工资大于15000,显示B
        如果工资大于10000,显示C
        其他的显示为D
        SELECT salary,
        CASE
        WHEN salary>=20000 THEN 'A'
        WHEN salary>=15000 THEN 'B'
        WHEN salary>=10000 THEN 'C'
        ELSE 'D'
        END AS 级别
        FROM employees;
    5.2分组函数---统计函数、聚合函数、组函数
        分类:
            sum求和、avg平均数、max最大值、min最小值、count计算个数
        特点:
            1.sum,avg一般用于处理数值型
            2.max,min,count可以处理任何类型
            3.所有分组函数都忽略null值
            4.可以和DISTINCT去重搭配使用
            5.count
     (1)SELECT SUM(salary) AS 工资总和 FROM employees;
     (2)SELECT AVG(salary) AS 工资平均 FROM employees;
     (3)SELECT MAX(salary) AS 最大值 FROM employees;
     (4)SELECT MIN(salary) AS 最小值 FROM employees;
     (5)SELECT COUNT(salary) AS 字段总和 FROM employees;
     (6)SELECT SUM(salary) 和,AVG(salary) 平均值,MAX(salary) 最大,MIN(salary)最小,COUNT(salary)个数总和 FROM employees;
   6.分组查询
        语法:select 查询列表 from 表名 where 筛选条件 group by 分组字段;
        注意:1.查询列表必须特殊,要求是分组函数和GROUP BY 后出现的字段
             2.
                针对的表               位置            关键字
重点 分组前筛选: 原始表                 group by前      WHERE
    分组后帅选: group by的结果集          group by后     Having
    WHERE和Having的区别:
        1.分组前筛选用where
        2.分组后筛选用Having
        3.WHERE不能使用列别名和聚合函数(sum,avg,count)
     (1)查询各个job_id的员工工资的最大值,最小值,平均值,总和,并按照job_id升序
        SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary),job_id FROM  employees GROUP BY job_id ORDER BY job_id ASC;
     (2)查询各个管理者手下的员工最低工资,其中最低工资不能低于6000,
        没有管理者的员工不计算在内
        SELECT
            MIN(salary),manager_id
        FROM
            employees
        WHERE
            manager_id IS NOT NULL
        AND salary >= 6000
        GROUP BY
            manager_id;
     (3)查询每个部门的员工个数
        SELECT COUNT(department_id),department_id FROM employees GROUP BY  department_id;
     (4)查询每个工种的员工平均工资
        SELECT AVG(salary),job_id FROM employees GROUP BY job_id;
     (5)查询每个位置的部门个数
        SELECT COUNT(department_id),location_id FROM departments GROUP BY  location_id;
     (6)查询邮箱中包含a字符的,每个部门的最高工资
        SELECT MAX(salary),email,department_id FROM employees WHERE email   LIKE '%a%' GROUP BY department_id;
     (7)查询有奖金的每个领导手下员工的平均工资
        SELECT AVG(salary),manager_id FROM employees WHERE commission_pct   IS NOT NULL GROUP BY manager_id;
难点 (8)查询哪个部门的员工个数大于5
        1.查询 每个部门的所有员工个数
        2.筛选出大于5的
        SELECT COUNT(*) AS 员工个数,department_id FROM employees GROUP BY   department_id HAVING COUNT(*)>5;
     (9)查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
        1.查询每个工种有奖金的员工的工种编号和最高工资
        2.在此基础上筛选出工资>12000
        SELECT MAX(salary),job_id FROM employees WHERE commission_pct is  NOT NULL GROUP BY job_id HAVING MAX(salary)>12000;
      (10)查询管理者编号>102的每个管理者手下员工最低工资大于5000的管理者编号和最低工资
        1.查询管理者编号>102的每个管理者编号和最低工资
        2.在此基础上筛选管理者手下员工最低工资大于5000
        SELECT manager_id,MIN(salary) FROM employees WHERE manager_id>102  GROUP BY manager_id HAVING MIN(salary)>5000;
     (11)查询每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,
         按最高工资降序排序
        *注意:排序写在分组之后*
        SELECT
            job_id,
            MAX(salary)
        FROM
            employees
        WHERE
            commission_pct IS NOT NULL
        GROUP BY
            job_id
        HAVING
            MAX(salary)>6000
        ORDER BY
            MAX(salary) DESC;
     (12)*多个字段分组查询*
        查询每个工种每个部门的最低工资,按最低工资降序排序
        SELECT
            job_id,
              department_id,
            MIN(salary)
        FROM
            employees
        GROUP BY
            job_id,department_id
        ORDER BY
            MIN(salary) DESC;
作业:1.思考分组函数是否能放在WHERE之后
        sql语句中,where必须放在group之前,因为分组查询是根据WHERE条件查询出来的数据作为结果的,也就是说,分组必须对WHERE选择后的结果进行分组,不能直接对原表进行分 组
     2.练习之前内容
   7.连接查询
        笛卡尔乘积现象:表1有n行,表2有m行,结果是m*n行
        发生原因:没有添加有效的连接条件
        如何避免:添加有效的连接条件
    分类:
     1.按照年代区分:
        sql192标准:仅仅支持内连接
        sql199标准:支持内连接,外连接,交叉连接
     2.按照功能区分:
        内连接:等值连接
               非等值连接
               自连接
        外连接:右外连接
               左外连接
               全外连接
        交叉连接:
    7.1 sql92连接:内连接
                    等值连接:
                    1.多表等值连接的结果是多表的交集部分
                    2.n表连接,至少需要n-1个条件
                    3.多表的顺序没有要求
                    4.一般情况下要为表起别名
                    5.可以搭配前面使用的所有子句使用,比如排序,分组,筛选
                    非等值连接:不完全是不等值连接,还可以是其他连接(大于,小于或者其他关系)
                    自连接:相当于等值连接
        sql99标准:内连接 inner
                  外连接:右外连接:right(outer)
                         左外连接:left(outer)
                         全外连接:full(outer)
                  交叉连接:cross
        语法:select 查询列表 from 表1 别名 连接类型 表2 别名
             on 连接条件
             where 筛选条件
             group by分组
             having 筛选条件语句
             order by排序
            内连接:Inner(重要!!!)
            语法:select 查询列表 from 表1 别名 inner join 表2 别名
                 on 连接条件;
                等值连接
                1.添加排序,分组,筛选
                2.inner可以省略
                3.筛选条件写在where后面,连接条件写在on后面
                4.查询内容是多表的交集部分
                非等值连接
                自连接
            外连接:用来查询一个表中又而另外一个表中没有的数据
              特点:
                1.外连接的查询结果是主表的所有结果,如果从表中有和主表信息匹配的,则会显示匹配的值,如果从表中没有和主表信息匹配的,则会显示null
                2.外连接的查询结果=内连接的结果+主表中有而从表中没有的值
                3.左外连接:left(outer)左边是主表
                  右外连接:right(outer)右边是主表
                  全外连接:full(outer)
                4.左外和右外调换两个表的顺序,可以实现同样的效果
            交叉连接:cross
              特点:九九乘积  
        总结:sql92标准和sl99标准:
            1.ssql99标准支持的连接类型较多
            2.可读性高,实现了连接条件和筛选条件的分离
     (1)/*sql92标准联表查询*/
        查询员工名和对应的部门名
        SELECT
            last_name,
            department_name
        FROM
            employees AS e,
            departments AS d
        WHERE
            e.department_id=d.department_id;
     (2)查询员工名,工种号,工种名
        SELECT last_name,e.job_id,job_title
        FROM employees AS e,jobs AS j
        WHERE e.job_id=j.job_id;
     (3)/*进行联表查询的筛选*/
        查询有奖金的员工名和部门名
        SELECT last_name,department_name,commission_pct
        FROM employees AS e,departments as d
        WHERE e.department_id=d.department_id AND commission_pct IS NOT             null;
     (4)查询城市名中第二个字符为o的部门名和城市名*/
        SELECT department_name,city
        FROM locations l,departments d
        WHERE l.location_id=d.location_id AND city LIKE '_o%';
     (5)/*可以添加排序*/
        查询每个工种的工种名和员工的个数,并且按照员工个数降序排序
        SELECT job_title,COUNT(*)
        FROM employees AS e,jobs AS j
        WHERE e.job_id=j.job_id
        GROUP BY job_title
        ORDER BY COUNT(*) DESC;
     (6)/*可以实现三表连接*/
        查询员工名,部门名,所在城市且城市首字母为s
        SELECT last_name,department_name,city
        FROM employees e,departments d,locations l
        WHERE e.department_id=d.department_id
        AND d.location_id=l.location_id
        AND city LIKE 's%';
难点 (7)/*非等值连接*/
        查询员工的工资和工资等级
        SELECT salary,grade_level
        FROM employees e,job_grades g
        WHERE salary BETWEEN g.lowest_sal AND g.highest_sal
难点 (8)/*自连接*/
        查询员工的名和上级的名称
        SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
        FROM employees e,employees m
        WHERE e.manager_id=m.employee_id;    
     (10)/*sql99标准联表查询*/
         /*内连接 等值连接*/
        查询员工名和部门名
        SELECT last_name,department_name
        FROM employees e INNER JOIN departments d
        ON e.department_id=d.department_id
     (11)查询名中包含e的员工名和工种名
        SELECT last_name,job_title
        FROM employees e INNER JOIN jobs j
        ON e.job_id=j.job_id/*联表条件*/
        WHERE last_name LIKE '%e%';/*筛选条件*/
     (12)查询部门个数>3的城市名和部门个数
        每个城市部门个数,筛选大于三个的
        SELECT city,COUNT(*)
        FROM locations l INNER JOIN departments d
        ON l.location_id=d.location_id
        GROUP BY city
        HAVING COUNT(*)>3;
     (13)查询部门的员工个数大于3的部门名和员工个数,并且按照员工个数降序
        SELECT COUNT(*),job_title
        FROM employees e INNER JOIN jobs j
        ON e.job_id=j.job_id
        GROUP BY department_id
        HAVING COUNT(*)>3;
        ORDER BY COUNT(*) DESC;
重点  (14)/*三表联查*/
        查询员工名,部门名,工种名并且按照部门名降序
        SELECT last_name,department_name,job_title
        FROM employees e
        INNER JOIN departments d
        ON e.department_id=d.department_id
        INNER JOIN jobs j
        ON e.job_id=j.job_id
        ORDER BY department_name DESC;
     (14)/*非等值连接*/
        查询员工的工资和工资级别
        SELECT salary,grade_level
        FROM employees e INNER JOIN job_grades g
        ON e.salary BETWEEN g.lowest_sal AND g.highest_sal;
     (15)查询员工工资级别的个数>20的个数,并且按照工资级别降序排序
        SELECT COUNT(*),grade_level
        FROM employees e INNER JOIN job_grades g
        ON e.salary BETWEEN g.lowest_sal AND g.highest_sal
        GROUP BY grade_level
        HAVING COUNT(*)>20
        ORDER BY grade_level DESC;
难点 (16)/*自连接*/
        查询员工的名和上级的名称
        SELECT e.last_name,m.last_name
        FROM employees e JOIN employees m
        ON e.manager_id=m.employee_id;    
难点 (17)/*外连接*/
        查询男朋友信息不在男生表的女生名(女生表是主表)
        SELECT     b.name,bo.*
        FROM beauty b LEFT JOIN boys bo
        ON b.boyfriend_id=bo.id;
     (18)查询哪个部门没有员工(部门表是主表)
        SELECT d.*,employee_id
        FROM departments d LEFT JOIN employees e
        ON d.department_id=e.department_id
        WHERE employee_id IS NULL;
     (19)/*全外连接*/
        查询部门信息以及员工信息
        SELECT d.*,e.*
        FROM departments d FULL JOIN employees e
        ON d.department_id=e.department_id;
     (20)/*交叉连接*/
        SELECT d.*,e.*
        FROM departments d CROSS JOIN employees e;
难点8.子查询
    含义:出现在其他的查询语句中select语句,又称为内查询语句,(子查询语句的)外部查询语   句称为主程序语句
    分类:按照子查询语句出现位置:
            select后面
                标量子查询
            from后面
                表子查询
            where和Having后面(重要!!!)
                标量子查询
                列子查询
                行子查询
            exists后面
                表子查询
         按照结果集的行列数不同:
            标量子查询(结果集只有一行一列)
            列子查询(结果集有一列多行)
            行子查询(结果集有一行多列)
            表子查询(结果集有多行多列)--相关子查询
    8.1 where或Having后面(重要!!!)
            标量子查询(单行)
            列子查询(多行)
            行子查询
        特点:1.子查询语句放在()里面
             2.子查询一啊不能放在条件的右侧
             3.标量子查询,一般情况下搭配单行操作符使用(< > >= <= <>)
               列子查询,一般情况下搭配多行操作符使用(in any/some all)
                in/not in:等于列表中的任意一个
                any/some:任一,和子查询返回的某一个值做比较
               all:和子查询返回的每一个值作比较
    8.2 select后面(仅仅支持标量子查询),不常用
    8.3 from后面,表子查询,将子查询结果看成表来用,要求必须起别名  
    8.4 exists后面,相关子查询
        语法:exists(完整查询语句)
        结果:1和0         
     (1)/*where或Having后面(重要)  标量子查询(单行)*/
        谁的工资比Abel高?
        1.Abel的工资是多少
        2.比较谁的工资高于Abel
        SELECT *
        FROM employees
        WHERE salary>(
        SELECT salary
        FROM employees
        WHERE last_name='Abel'
        );
     (2)查询job_id与141号员工相同,
        salary比143号员工多的员工姓名,job_id和工资
        SELECT last_name,job_id,salary
        FROM employees
        WHERE job_id=(
        SELECT job_id FROM employees WHERE employee_id=141)
        AND salary>(
        SELECT salary FROM employees WHERE employee_id=143);
作业:
    1.显示所有员工的姓名,部门号和部门名称。
    2.查询90号部门员工的job_id和90号部门的location_id
    3.选择所有有奖金的员工
    4.选择city在Toronto工作的员工
    5.查询每个工种、每个部门的部门名、工种名和最低工资
    6.查询每个国家下的部门个数大于2的国家编号
    7.选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式
    employees    Emp#    manager    Mgr#
    kochhar        101    king    100
重点:(3)/*HAVING后面的标量子查询*/
        查询最低工资大于50号部门最低工资的部门和其最低工资
        1.查询50号部门的最低工资
        2.查询每个部门最低工资
        3.大于50号部门
        SELECT
            MIN(salary),
            department_id
        FROM
            employees
        GROUP BY
            department_id
        HAVING
            MIN(salary) > (SELECT MIN(salary) FROM employees WHERE   department_id = 50);
     (4)/*列子查询*/
        查询Location_id是1400或者1700的部门中的所有员工姓名
        1.查询Location_id是1400或者1700的部门编号
        2.查询员工姓名,要求部门号是第一次查询列表中的某一个
        SELECT
            last_name
        FROM
            employees
        WHERE
            department_id IN (SELECT department_id FROM departments
            WHERE location_id IN (1400, 1700));
     (5)查询其他工种中比job_id为'IT_PROG'工种任意一个工资低的
        员工的员工号、姓名,job_id和salary
        SELECT DISTINCT employee_id,last_name,salary,job_id
        FROM employees
        WHERE
        salary <ANY(SELECT salary FROM employees WHERE job_id='IT_PROG')  AND job_id<>'IT_PROG';
     (6)/*行子查询*/
        查询员工编号是最小的并且工资最高的员工信息
        1.查询最小的员工编号
        2.查询最高工资
        3.查询员工信息
        SELECT * FROM employees
        WHERE(employee_id,salary)=
        (SELECT MIN(employee_id),MAX(salary) FROM employees);
     (7)/*selsect后面*/
        每个部门的员工个数
        SELECT d.*,(
        SELECT COUNT(*) FROM employees e
        WHERE e.department_id=e.department_id
        ) 个数
        FROM departments d;
     (8)查询员工号=102的部门名
        SELECT(
        SELECT department_name FROM departments d
        JOIN employees e ON d.department_id=e.department_id
        WHERE e.employee_id=102
        ) 部门名;
     (9)/*from后面*/
        查询每个部门的平均工资的工资等级
        1.查询每个部门的平均工资(子查询出的结果作为一个新表并起别名ag_dep)
        2.查询工资等级*/
        SELECT ag_dep.*,g.grade_level
        FROM (
        SELECT AVG(salary) ag,department_id
        FROM employees
        GROUP BY department_id
        ) AS ag_dep JOIN job_grades g ON ag_dep.ag BETWEEN lowest_sal AND  highest_sal;
     (10)/*exists后面*/
        SELECT EXISTS(SELECT employee_id FROM employees);/*1*/

        SELECT EXISTS(
        SELECT employee_id FROM employees
        WHERE salary=30000
        );/*0*/          
   9.分页查询
    应用场景:当要显示的数据,一页显示不全的情况下就需要sql提交请求
    语法:
        select 查询列表 from 表名 联表类型(join type)
        on 连接条件
        where 筛选条件
        group by 分组条件
        having 筛选条件
        order by 排序的字段  
        limit(offset,size分页关键词)       
    特点:
        1.limit语句放在查询语句的最后
        2.公式:limit[offset,size]
               offset:要显示条目的起始索引(从0开始)
               size:要显示的具体条目个数
        要显示的页数page
        每页的条目数size
        select 查询列表
        from 表名
        limit 页数,size
        limit(page-1)*size,size
     (1)/*分页查询*/
        查询前五条员工信息
        SELECT * FROM employees LIMIT 5;
     (2)查询第11条-15条员工信息*/
        SELECT * FROM employees LIMIT 10,5;
     (3)查询有奖金的员工信息,并且工资较高的前十名显示出来*/
        SELECT * FROM employees
        WHERE commission_pct IS NOT NULL
        ORDER BY salary DESC
        LIMIT 10;
作业:
难点1.查询有员工的部门名#EXISTS*/
        SELECT
             department_name
        FROM
             departments d
        WHERE
           EXISTS(
              SELECT * FROM employees e
              WHERE e.department_id = d.department_id
         );
    2.查询公司工资最少的员工的last_name,job_id和salary*/
        SELECT last_name,job_id,salary
        FROM employees
        WHERE salary=(SELECT MIN(salary) FROM employees);
   10.union联合查询
    概念:将多条查询语句的结果集合并成一个结果    
    语法:
        查询语句 1 union 查询语句2 union ...
    特点:1.要查询的结果来自于多个表而且多个表之间没有直接的连接关系,但是查询的信息一致
         2.联合查询的列数要保持一致
     (1)查询部门编号大于90或者邮箱包含a的员工信息
        SELECT * FROM employees WHERE department_id>90
        union
        SELECT * FROM employees WHERE email LIKE '%a%';
难点 (2)查询没有奖金和在us工作的员工信息
        SELECT * 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 commission_pct IS NULL
        UNION
        SELECT * 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 country_id='US';  
六.DML语言的学习
   1.插入语言语句inserst
    语法:
        insert into 表名(列名...) values(值...)
    注意:1.插入的值的字段必须和值匹配
         2.插入的值的类型必须和字段的数据类型一致
         3.不可以为null(非空)的列必须插入
           可以null的列如何插入数据信息
           3.1给出列名并填写null值
           3.2列名和值名都不写
         4.列的顺序可以进行调换(数值顺序也要跟随列内容的调换)
         5.列数和值的个数必须一致
         6.可以省略列名,默认所有列,一定要注意插入信息列的顺序和表中的列的顺序一致
    语法二:
        insert into 表名(列名...)
        set 列名=值,列名=值,...
    两种写法的区别,第一种插入数据写法支持:
        1.支持批量添加数据
        2.支持子查询
   2.修改语句update
    修改表记录(修改表的一部分,不是全部)
    1.修改单表的记录
      对于单个或者多个列名都可以修改相应的值
    语法:
        update 表名(1)
        set 列名=值,列名=值...(3)
        where 筛选条件;(2)
    2.修改多表的记录
    注意:表必须写别名
    语法:
    sql92标准:
        update 表1 别名,表2 别名
        set 列=值...
        where 联表条件
        and 筛选条件;
    sql99标准:
        update 表1 别名
        inner/left/right 表2 别名
        on 联表条件
        set 列=值...
        where 筛选条件;
   3.删除语句delete
    1.delete整行删除,一删一行
    语法:
     1.1单表删除
        delete from 表名 where 筛选条件;
     1.2多表删除
        sql92标准:
            delete 别名,别名...
            from 表1 别名,表2 别名...
            where 联表条件
            and 筛选条件;
        sql99标准:
            delete 别名,别名...
            from 表1 别名,表2 别名...
            inner/left/right 表3 别名...
            on 联表条件
            where 筛选条件;
    2.truncate整表删除(清空删除)
    语法:turncat tables 表名;
   4.delete和truncate的区别:
     1.delete可以加where筛选条件,truncate可以加
     2.turncat删除的效率高一点
     3.假如需要删除的表中有自增长列
      如果用delete删除后,再插入数据,自增长列的值从断点开始
      truncate删除后,再插入数据,自增长列的值从1开始
     4.delete删除有返回值,truncat删除没有返回值
     5.truncat删除不能回滚,delete删除能回滚
    #插入语言
        INSERT into beauty(id,name,sex,borndate,phone,photo,boyfriend_id)
        VALUE('13','Lisa','女','1997-05-05','17793495062',NULL,2);
        SELECT * FROM beauty;
    #非空的信息插入
        INSERT into beauty(id,name,sex,borndate,phone,boyfriend_id)
        VALUE('14','邓文亭','女','1998-12-08','17793495063',2);
    #插入信息的顺序
        INSERT into beauty(name,sex,id,borndate,phone,photo,boyfriend_id)
        VALUE('孙俪','女','15','1987-05-05','17793495064',NULL,2);
    #列数和值的个数必须一致
        INSERT into beauty(name,sex,id,borndate,phone)
        VALUE('关晓彤','女','16','1987-01-01','17793495064');
    #省略列名,写入相关值
        INSERT into beauty
        VALUE('17','丫丫','女','1987-056-05','17793495068',NULL,2);
    #插入数据的语法二
        INSERT into beauty
        SET id=18,name='周扬青',phone='11111111111';
    #两种写法的区别
        INSERT INTO beauty
        VALUES
        ('19','赵1','女','1998-12-05','145623787',NULL,2)
        ('20','赵2','女','1998-12-06','145623789',NULL,3);
    #支持子查询
        INSERT into beauty(id,name,phone)
        SELECT 21,'宋茜','10000';
    #修改语句update
    #单表中种单个字段数据修改
        update beauty
        set phone='114'
        where name LIKE '赵%';
    #单表中多个字段数据修改
        update boys
        set boyName='彭于晏',userCP='1000'
        where id=2;
    #多表中的修改
    #修改张无忌的女朋友的手机号为111111
    #先找到张无忌的女朋友,再去修改号码
        UPDATE boys bo
        INNER JOIN beauty b
        ON bo.id=b.boyfriend_id
        SET b.phone='1111111'
        WHERE bo.boyName='张无忌';
难点#修改没有男朋友的女生的男朋友编号都是2号
        UPDATE boys bo
        RIGHT JOIN beauty b
        ON bo.id=b.boyfriend_id
        SET b.boyfriend_id=2
        WHERE bo.id is NULL;
    #删除
    #单表删除
        DELETE FROM beauty WHERE name LIKE '宋%';
    #多表删除
    #删除张无忌的女朋友的信息
    DELETE b
    FROM boys bo
    INNER JOIN beauty b
    ON bo.id=b.boyfriend_id
    WHERE bo.boyName='张无忌';
    #删除黄晓明的信息以及他的女朋友的信息
    DELETE b,bo
    FROM boys bo
    INNER JOIN beauty b
    ON bo.id=b.boyfriend_id
    WHERE bo.boyName='黄晓明';
    #整表删除
    TRUNCATE TABLE boys;
七.DDL语言的学习--数据定义语言
    创建 create
    修改 alter
    删除 drop
    库和表的管理
   1.库的管理
    创建 CREATE DATABASE IF NOT EXISTS 库名;
    修改
       修改库名 RENAME DATABASE 旧库名 to 新库名;
       修改库的字符集 ALTER DATABASE 库名 CHARACTER SET utf8;
    删除 DROP IF EXISTS database 库名
   2.表的管理
    创建 create table 表名(列名 列的类型【(长度),约束 】,。。。);
    修改
        修改表名      ALTER TABLE 旧表名 RENAME TO 新表名;
        修改列名      ALTER TABLE 表名 CHANGE COLUMN 旧列名 新列名 数据类型;
        修改列的类型   ALTER TABLE 表名 MODIFY COLUMN 列名 数据类型;
        添加新列      ALTER TABLE 表名 ADD COLUMN 新列名 数据类型;
        删除列       ALTER table 表名 DROP COLUMN 列名;
    删除
        删除表 DROP TABLE IF EXISTS 表名;
    复制
        仅仅复制表的结构 CREATE TABLE 表名 LIKE 被复制的表;
        只复制表的部分字段(部分列) CREATE TABLE 表名 SELECT 字段 FROM     被复制的表 WHERE 0;
        复制表结构和数据 CREATE TABLE 表名 SELECT * FROM 被复制的表;
        只复制表的部分数据 CREATE TABLE 表名 SELECT 字段 FROM 被复制的表
                        WHERE 约束条件;
   3.常见数据类型介绍(内容开始部分)
   4.约束
    含义:一种限制,用来限制表中的数据,为了保证数据的可靠性和准确性
        CREATE TABLE 表名(
            字段名 字段类型 列级约束
            表级约束
        )
        添加约束的时机:
           1.创建表时
           2.修改表时
        约束的分类:
           列级约束:支持六大约束,外键约束没有效果
           表级约束:除了非空,默认约束其他都支持
    常见约束:
难点:   六大约束:
        not null:非空约束,用来保证该字段不能为空(姓名,学号)                          default:默认约束,用来保证该字段有默认值(性别)
        primary key:主键约束,用来保证该字段的值具有唯一性,并且非空(员工编号)
        unique:唯一约束,用来保证该字段的值具有唯一性,对应的值可以为空(座位)
        check:检查约束【mysql不支持check约束】(性别)
        foreing key:外键约束,用来限制两个表的关系(reference连接的关键字)
                    要有保证连接两表的字段
                    用来保证该字段的值必须来自主表的关联列
    4.1创建表时添加约束
        列级约束:直接在字段名和类型后面追加约束类型,支持默认,非空,唯一,主键
        表级约束:在所有字段的最后面
                CONSTRAINT 约束名 约束类型(字段名)【reference 表名(字段名)】
     #通用写法,创建表的时候列级约束以及表级约束都有添加
        CREATE TABLE if not EXISTS stuifo(
        id INT PRIMARY KEY, #主键
        stuName VARCHAR(20) PRIMARY KEY,#非空
        gender CHAR(1) CHECK(gender='男' OR gender='女'), #检查
        seat INT UNIQUE,#唯一
        age INT,
        majorId INT,#外键
        CONSTRAINT fk_stuifo_major FOREIGN KEY(majorId) REFERENCES   major(id)
        );
     #查询某表中的索引,包括主键,外键,唯一键
        SHOW INDEX FROM stuifo;
    4.2修改表时添加约束:
        列级约束:ALTER TABLE 表名 MODIFY COLUMN 字段 字段类型 新约束;
        表级约束:ALTER TABLE 表名 MODIFY add 新约束(字段);
     #在修改表时添加非空,默认,主键,外键约束
        ALTER TABLE stuifo MODIFY COLUMN stuName VARCHAR(20) NOT NULL;
        ALTER TABLE stuifo MODIFY COLUMN age INT DEFAULT 18;
        ALTER TABLE stuifo MODIFY COLUMN id INT PRIMARY KEY;#列级
        ALTER TABLE stuifo ADD PRIMARY KEY(id);#表级
        ALTER TABLE stuifo ADD CONSTRAINT fk_syuifo_major
        FOREIGN KEY(majorId) REFERENCES major(id);#外键
    4.3修改表时删除约束
     #修改表时删除约束
     #1.删除非空约束
        ALTER TABLE stuifo MODIFY COLUMN stuName VARCHAR(20);
     #2.删除主键约束
        ALTER TABLE stuifo DROP PRIMARY KEY;
      #3.删除外键约束???
        ALTER TABLE stuifo DROP FOREIGN KEY fk_syuifo_major;
   5.标识列
    含义:类似于约束得自增长列
         可以不用手动插入值,系统提供默认的序列值
         auto_increment_increment每次增长的步长值
         auto_increment_offset偏移量(起始值)
    特点:1.一个表里的标识列至多只能有一个
         2.标识列不一定和主键约束一起使用
           标识列必须和约束一起使用
         3.标识列可以进行数据设置 set auto_increment_increment=值(步长)
    添加标识列的时机:
         1.创建表时
         2.修改表时添加
         alter table 表 modify column 字段 约束 auto_increment;
         3.修改表时删除
         alter table 表 modify column 字段;
     #标识列
     #创建时设置标识列
        CREATE TABLE tab_inndentity(
        id INT PRIMARY KEY auto_increment,
        NAME VARCHAR(20)
        );
        INSERT INTO tab_inndentity VALUES(
        1,'Ellen'
        );
        INSERT INTO tab_inndentity VALUES(
        NULL,'Ivy'
        );
     #查看步长,起始值
        SHOW VARIABLES LIKE '%auto_increment%';
     #设置自增步长
        SET auto_increment_increment=3;
八:DCL语言的学习:事务控制语句
   1. 事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执 行,相互依赖
   2. 事务处理:
        回滚:事务执行失败,所有受到影响的数据将回到事物开始之前的状态
             反之如果单元中的所有sql语句都执行成功,则事务被顺利执行
   3.事务的特性ACID:
    3.1原子性(Atomicity)
       一个事物不可分割,执行单元要么全部执行,要么全部不执行
    3.2一致性(Consistency)
       一个事物会使数据从一个统一状态切换到另一个统一状态
    3.3隔离性(Isolation)
       事物之间的各自sql语句执行过程不受其他事物打扰
    3.4持久性(Durability)
       一个事物一旦提交,则会永久的改变数据库的数据
   4.事物创建
    检查事务提交的状态
    4.1隐式事务的创建:事务没有明显的开启和结束的标记
       insert update delete
    4.2显式事务的创建:事务有明显的开启和结束的标记
       1.注意,显示事务的创建之前必须禁用自动提交功能
         SET autocommit=0;
       2.开启事务
         SET autocommit=1;
         START TRANSACTION;(可选)
       3.编写事务中sql语句(select insert update delete)
         语句一;
         语句二;
          ......
       4.结束事务
         Rollback;回滚
         Commit;提交
         Savepoint;设置节点保存  
     ##显示自动提交功能     
        SHOW ENGINES;
        SHOW VARIABLES LIKE 'autocommit';
     ##关闭事务
        SET autocommit=0;
     ##开启事务
        SET autocommit=1;
        START TRANSACTION;

     (1)CREATE TABLE account(
        id INT PRIMARY KEY auto_increment,
        username VARCHAR(20),
        balance DOUBLE
        );
        INSERT INTO account(username,balance)
        VALUES('玄彬',1000),('元彬',1000);
        SELECT * FROM account;

        SET autocommit=0;
     #创建事务sql语句
      #成功
        UPDATE account SET balance=500 WHERE username='玄彬';
        UPDATE account SET balance=1500 WHERE username='元彬';
     #结束事务
        COMMIT;
        SELECT * FROM account;
     #失败
        UPDATE account SET balance=1000 WHERE username='玄彬';
        UPDATE account SET balance=1000 WHERE username='元彬';
     #回滚事务
        ROLLBACK;
        SELECT * FROM account;
九:视图的讲解
    含义:虚拟的表,和数据库中的普通表一样使用
    创建:create view 视图名
         as 查询语句
    删除:drop view 视图名

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值