DB

数据库(database):存储数据的仓库,一系列有组织的数据

DBMS

数据库管理系统,mysql就是其中的一种数据管理系统。不要和DB混淆

SQL

结构化查询语言

先把数据放到表中,表再放到库中

一个数据库中有多个表,每个表都有名字,不能重复

表有一些特性,这些特性定义了数据在表中如何存储,类似Java中“类”的设计

表由列组成,我们也叫做字段,所有的表都是由一个或多个列组成的

表中的数据是按行储存的,一行就代表了类似Java中的对象,一些就代表了java中的属性。

DBMS分为两类

一个是基于文件系统的DBMS(Access)、

一个是基于客户机,这个需要安装软件,我们一般讲安装数据库,就是指安装数据库的服务端

###

###

###

d基础查询

select 查询列表 from 表名;-----可以查询表中的字段,常量值,表达式,函数,查询之后的结果是一个虚拟的表格,不是真实存在的,也可以查询多个字段,当查询全部字段的时候,可以把查询列表用*代替,但是这样不好的地方就是最后运行出来的虚拟表的字段顺序是固定的,当你需要自己规定顺序的时候,就只能一个字段一个字段的打出来。

建议在进行操作之前,在前面加一行使用的代码,“USE 库名”;

也可以查询常量值:select 100;

在mysql中是不区分字符和字符串的,没有字符串的概念,都用单引号来引用

也可以查询表达式

也可以查询函数

select后面可以跟某个表的字段名(可以等同看做变量名),也可以跟字面量(字面值)也就是数据,当它是数据的时候,可以借助在这个表的结构,把数据填写进去

字段取别名

1,方便我们理解

2,如果要查询的字段有重名的情况,我们使用别名可以区分开来。

方式一:

SELECT 100 AS 要取的别名;

SELECT NAME AS 姓名 FROM 库名、

方式二:

可以直接省略AS,效果是一样的

去重

比如,我使用查询的时候,出现了重复值,但是我不需要重复,所以,我就可以在SELECT后面加上DISTINCT

加号(+)

在mysql中的加号,只有一个功能,就是运算符

当两个操作数都是数值型的时候,就做加法运算

当其中一方是字符型,另一方是数值型的时候,就试图把字符型转化成数值型,如果转化成功,就做加法运算,如果转化失败,那就将字符性的数值转化成0,然后再进行运算。

当其中任意一方为NULL,不管另一方是什么,结果都为NULL

字段链接

用CONCAT( ,);

判断是否空值,IFNULL( ,);

在括号前面写的是想要判断的表达式,当前面的表达式是NULL的时候,返回值就是后面的那个数字。当前面的表达式不是NULL的时候,返回值就是本身

条件查询

格式:

SELECT

查询列表

FROM

表名

WHERE

筛选条件;

分类:

1,按条件表达式筛选-----比如大于小于这些,就叫条件表达式,要注意的一点就是,在mysql中的不等于的写法就是!=或者<>

2,按逻辑表达式筛选-----逻辑运算符:&&(与) ||(或) !(非)或者也可以写成AND(与)OR(或)NOT(非)

与:两个条件都为true,结果为true

或:只要有一个条件为true,结果就为true

非:如果连接的条件本来为真,那么就为假。

3,模糊查询-----like ,between and ,in ,is null

注意:在WHERE中有两个条件的时候,我们要在中间使用AND连接条件

显示表的结构,并查询其中的全部数据

DESC 表名;-----可以显示表的结构,对应的类型,附加的约束

SELECT * FROM 表名;-----可以显示详细的信息

拼接练习

显示出表employees的全部列,各个列之间用逗号连接,列头显示OUT-PUT

SELECT

CONCAT( ,‘,‘, ) AS OUT-PUT

FEOM

employees;

IFNULL( ,)-----判断空值

在左边是要判断有可能为null的表达式。右边的参数是如果是null,那么返回值应该是多少。

模糊匹配like关键字

比如,如果想查询员工名中包含字符a的员工信息,就可以在最后面加一个LIKE'%a%'-----这个就相当于,a可能出现在名字中的任何地方,这里的百分号就是一种通配符 ,代表任意多个字符,包含0个字符

特点:一般和通配符%搭配使用,_下划线代表了任意单个字符,如果要查询的字符是下划线,那就在下滑线前加一个转义字符\,或者用另一种转义方法-----

like'&-' ESCAPE'&'

模糊匹配between and关键字

查询员工编号在100到120之间的员工信息

特点:

可以提高简洁度

他是包含临界值的

模糊匹配in关键字

查询员工的工种编号是IT,AD中的一个员工名与员工编号

WHERE 要查询的表 IN( 'IT' , 'AD' );

特点:

提语句的简洁度

in列表的值类型必须统一或者兼容

在in的列表中不能使用通配符等

模糊匹配is null关键字

查询没有奖金的员工名和奖金率

注意:这里不能使用=null,只能使用is null

如果是查询有奖金的员工名和奖金率,那就是is not null

判断符号不能用于判断null值

安全等于<=>

这个不但可以来判断null也可以用来判断普通的数值

排序查询

在基础查询中,只是显示原始的数据,现在要在原有的基础上再加一个排序的功能

它可以加在WHERE排序后面,写法是order by 加上排序列表 再加上是升序asc还是降序desc

常见函数

函数特点

类似java的方法,将一组逻辑语句封装在方法体中,对外暴露方法名的好处:

  1. 隐藏了实现细节

  2. 提高了代码重用性

调用:select 函数名(),根据需要,后面可以加from表

要记住函数名与函数功能

分类

  1. 单行函数

    concat,length,ifnull等

  2. 分组函数

    一般是做统计使用的

可以理解为,单行函数是进去一个值,返回一个值

分组函数是,进去很多值,返回一个值

单行函数(数据处理函数)

  • Lower-----转换小写

括号中放的是字段,可以把原本表中的大写转化成小写

  • Upper-----转化大写

和上面是相反的,其余相同

  • Substr-----取字符串

括号中有三个数值,第一个是被截取的字符串,第二个是起始下标,第三个是截取的长度,他们之间使用逗号分隔开

注意:

  1. 这里的起始下标是从1开始,没有0

  2. 这个可以放在where中进行使用,我认为最重要的是使用的灵活性

  • Length-----取长度

直接返回一个数字

  • Trim-----去空格

他可以去掉括号中的空白,这里的空白是指前后的空白

  • str_to_date-----把字符串转化成日期

    格式:

    str_to_date('字符串日期','日期格式')

    日期格式:

    %y年

    %m月

    %d日

    %h时

    %i分

    %s秒

    提示:

    如果你这条语句的写法恰好是年月日,那么就可以不使用这一条函数

  • date_format-----格式化日期

  • format-----设置千分位

  • round-----四舍五入

括号里面要填两个值,前面是要传入的数据,后面是小数点后保留的位数,如果是负数的话,那四舍五入的精度就再往前调一位

  • rand-----生成随机数

生成的随机数是0到1之间的,所以我们可以通过乘法来选择想要随机的位数,然后用四舍五入的方法来确定具体的位数

  • ifnull-----空处理函数

把null转化成一个具体值,专门处理空值,在所有数据库中,只要有null参与的数学运算,最重结果都是null,括号中有两个参数,左边是要判断的值,右边是如果这个值是null,那么把这个null当做什么,比如(a,1),就是把a中的null值都当做1来看待

  • case..when..then..when..then..else..end-----相当于if......else

使用场景:当员工的工作岗位是a的时候,工资上涨百分之10,当员工的工作岗位是b的时候,工资上涨百分之20

注意:这里不会修改数据库,只是将查询结果显示为上调之后的

分组函数(多行处理函数)

特点:

输入多行,最终只输出一行

注意:

如果你没有对数据进行分组,整张表默认为一组

分组函数必须要分组之后才能使用

  • count-----计数

  • sum-----求和

  • avg-----平均值

  • max-----最大值

  • min-----最小值

他们的用法都很简单,实地操作就能完成

分组函数注意事项

  1. 在分组函数中,自动会忽略null

  2. 分组函数中count(*)和count(具体的字段)有什么区别

    具体字段表示的是这个字段下所有不为null的元素的总数

    *是统计整张表的总行数(只要有一行数据,count++)

  3. 分组函数不能直接使用在where子句中

    因为分组函数使用的时候必须先分组才能使用,where执行的时候还没有分组,所以where后面就不能使用分组函数

  4. 所有的分组函数都可以组合起来一起用

group by分组查询

什么是分组查询

在实际的应用中,可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作,这个时候就要用到分组查询。

分组查询的格式

select

。。。

from

。。。

group by

。。。

使用场景举例

  • 计算每个部门的工资和

    实现思路:

    按照工作岗位分组,然后对工资求和

    select

    sum(工资的字段)

    from

    一个表单

    group by

    job-----这两句的意思就是说,按照工作进行分组

    注意:

    在一条select语句中,如果有group by语句的话,select后面只能跟参加分组的字段,以及分组函数,其他的一律不能跟

  • 找出每个工作岗位的最高薪资

    select

    工作岗位,max(薪资)

    from

    一个表单

    group by

    工作岗位-----后两句的意思就是按照工作岗位进行分组

  • 如果是要找“每个部门,不同工作岗位”的最高薪资

    有一个技巧:

    把两个字段连成一个字段看。

    也就是说group by 后面可以放两个字段

所有关键字的执行顺序

格式

select

。。。

from

。。。

where

。。。

group by

。。。

order by

。。。

以上关键字的顺序不能颠倒

顺序

  1. from

  2. where

  3. group by

  4. select

  5. order by

having字句过滤

比如最高薪资大于3000

group by

max(薪资字段)>3000

使用having可以对分完组之后的数据进一步的过滤,having不能单独使用,不能代替where,一定要和group by 联合使用

这个时候如果只使用 group by 效率就会比较低

遇到这种情况的时候,可以在where中先找出薪资大于3000的,然后在group by中进行分组

一般优先选择where,where完成不了了,再选择having

  • where没有办法的

    找出每个部门的平均薪资,要求显示平均薪资高于2500的

连接查询

他也可以叫做跨表查询,需要关联多个表进行查询

  • 表的连接方式

    1. 内连接

      1. 等值连接

        题目:查询每个员工所在的部门名称,显示员工名与部门名

        条件就是表a.部门编号=表b.部门编号

        因为条件是等量关系,所以被称为等值连接

        内连接两张表之间没有主次关系

        /*92的语法-----这种语法不清晰,后期进一步筛选*/
        SELECT
        		表a.人名,表b.工作名称
        FROM
        		表a,表b
        WHERE
        		表a.工作编号=表b.工作编号;
        #99的语法-----这种语法结构清晰,推荐使用,INNER可以省略
        SELECT
        		表a.人名,表b.工作名称
        FROM
        		表a
        INNER JOIN
        		表b
        on
        		表a.工作编号=表b.工作编号;
        #这个后面就可以继续加WHERE进行筛选
      2. 非等值连接

        题目:

        找出每个员工的薪资等级,要求显示,员工名,薪资,薪资等级

        思路:

        因为薪资等级是一个范围,就比如0到100是一级,所以在连接的 时候不是等于号,所以叫做非等值连接,大于0小于100用BETWEEN 0 TO 100

      3. 自连接

        就是一张表,本身与本身做连接,就比如10个人,互相是对方的领导,要求显示人和对应的领导

        技巧:

        把一张表看做两张表进行连接

    2. 外连接

      注意:

      外连接JOIN前面有个OUTER,是可以省略的,RIGHT是在OUTER JOIN前面

      1. 左外连接(左连接)

      2. 右外连接(右连接)

        在JOIN前面加一个RIGHT,意思就是除了刚开始进行内连接之外,还要把JOIN右边的表都查出来,就是把右边的表看成主表,捎带着关联查询左边的表

    3. 全连接

  • 当两张表进行连接查询的时候,没有任何条件限制,会发生什么现象

    现象就是,最终的查询条数,是两张表条数的乘积,这种现象被称为笛卡尔积

    • 如何避免笛卡尔积现象?

      在连接时加条件,满足这个条件的被筛选出来

      就比如,表a中有姓名和工作编号,表b中有工作编号和工作名称,如果我们要查询人名和工作名称,我们就需要表a的编号和表b的编号的工作编号相对应,对应的写法是

      /*92的语法-----这种语法不清晰,后期进一步筛选*/
      SELECT
      		表a.人名,表b.工作名称
      FROM
      		表a,表b
      WHERE
      		表a.工作编号=表b.工作编号;
      #99的语法-----这种语法结构清晰,推荐使用
      SELECT
      		表a.人名,表b.工作名称
      FROM
      		表a
      JOIN
      		表b
      on
      		表a.工作编号=表b.工作编号;
      #这个后面就可以继续加WHERE进行筛选

      这样子匹配也是按照笛卡尔积,只是最后显示出来的结果是经过筛选之后的看

    注意:

    通过笛卡尔积现象得出的结论就是,表连接的次数越多,效率就越低,所以尽量避免表的连接次数

多张表连接

语法:

就是在两张表连接的基础上,再在JOIN ON 后面继续加上JOIN ON

案例:

找出每个员工的部门名称以及工资等级,要求显示员工名,部门名,薪资,薪资,那就可以先连接两张表,然后再进行下一张表的连接

子查询

解释:

就是SELECT语句中嵌套SELECT语句,被嵌套的SELECT语句称为子查询语句

位置:

他可以出现在SELECT后面,FROM后面,WHERE后面

  • WHERE字句中出现子查询

    案例:

    找出比最低工资高的员工姓名和工资

    思考:

    1. 查询最低工资是多少

      SELECT
      		min(sal)
      FROM
      		emp

    2. 查询工资大于最低工资大于最低工资的

      SELECT 
      
      		name,sal 
      
      FROM 
      
      		emp 
      
      where 
      
      		sal>800
      		
    3. 合并上两句

      SELECT
      		name,sal
      FROM
      		emp
      WHERE
      		SELSET	min(sal)	FROM	emp

    上面的三步就是子查询的思路和实现

  • from中的子查询

    注意:

    他后面的子查询,可以将子查询的结果当做一张临时表(技巧 )

union合并查询结果集

比如查询工作是a和b的员工,我们可以

select name from emp where job=a or job=b;

但是也可以

select	name	from	emp	where	job=a
union
select	name	from	emp	where	job=b;

union的效率要更高

limit

作用:

就是把查询结果集的一部分取出来,通常用在分页查询当中,提高用户体验

用法:

比如limit5,这个意思就是取前五,limit后面可以跟两个数字,一个是起始下标,一个是取的长度,只放一个数字就是0,5的意思是0初始,取5位,也就是前五

位置:

limit是在order by之后执行的

分页

要求:每页显示3个信息

第一页:limit 0 3

第二页:limit 3 3

第三页:limit 6 3

第四页:limit 9 3

我们可以发现后面都是不变的,那前面的数字我们怎么样可以得到呢?

我们发现,前面的数字=(页数-1)*每页显示的条数

表的创建

格式:

create table 表名(字段名 数据类型,字段名 数据类型。。。。。。)

建议:

表名建议t_开始,字段名建议见名知意

数据类型

  • varchar

    可变长度的字符串,动态分配空间,节省空间

    最长是255

  • char

    定长字符串,使用不当的是时候可能会造成空间浪费,但是速度更快

  • int

    整数型

  • bigint

    数字中的长整型

  • float

    单精度

  • double

    双精度

  • date

    短日期 ,只包含年月日的信息

  • datetime

    长日期,还包含年月日时分秒

  • clob

    字符大对象

    最多存储4G的字符串

    比如存储一篇文章,一个简介,当超过255的时候,就可以选择他

  • blob

    二级制大对象

    专门存储图片,声音,视频,等流媒体

删除表

drop table 表名;-----这种删法当表不存在的时候会报错

drop table if exists 表名;-----如果这张表存在的话删除

插入数据insert

语法格式:

insert into 表名(字段名1,字段名2,字段名3)values(值1,值2,值3);-----字段名和值要一一对应,数量要对应,数据类型也要对应

注意:

insert语句但凡执行成功了都会多一条记录

在建表时可以在字段类型后面使用default 来指定初始值

insert插入日期

命名规范

  • 所有标识符都是小写

  • 单词和单词之间使用下滑线连接

修改

update

语法格式:

update 表名 set 字段名1=值1,字段名2=值2......where 条件

注意:

没有条件限制会导致所有数据全部更新。所以一般要加上限制条件

删除

delete from 表名 where 条件;

如果没有条件,整张表都会删除