sql
sql是一种结构化查询语言,目的是实现数据的储存、查询和更新,也是关系型数据通用语言;
SQL语言分为四部分
- DDL:数据定义语言‘
用于对结构的操作,例如创建数据库,表,等 - DML:数据操纵语言
用于对数据操作,例如增删改 - DCL:数据控制语言
用于授权收回等 - DQL:数据查询语言
用于数据查询
DMBS(数据库管理系统)
DMBS本质就是一个用于对数据进行管理、操纵的软件。
-
RDBMS:关系型的数据库管理系统
采用二元关系模型(表格形式) 也就是 行和列,与二维数组类似。 多用来储存数据关系简单的数据。 举例如下: Oracle: oracle公司 Mysql: 被oracle收购 Sql server: 微软 db2: ibm公司
-
Nosql: 非关系型的数据库管理系统
可储存复杂数据。例如图形 关系型数据库就无法存储。 nosql的出现就是用来弥补RDBMS的不足。 Redis: key-value 类型 Riak: 列储存数据库 MongoDB: 文档型数据库 Neo4J :图形数据库
Mysql数据库管理系统
特点: 关系型、开源免费(GPL许可证)、支持千万级别。
一个用户可创建多个数据库—>又可创建多个表,与oracle恰恰相反.
以下会介绍mysql 的分页,分组,排序,聚合函数,高级联合查询。
在此之前要明白一个概念,外键。外键顾名思义就是外表的键。
关系型数据库mysql所有数据之间的关系都是由外键来统治的,可以想象它的重要性。
如果不明白什么是键,推荐先学学集合再来学数据库。
第一张表emp员工表:
其中deptno就是emp表的外键,这个键来自于dept表。有了这个外键,两张表就有了联系。 比如jack 对应的deptno为10 ,那么jack对应的就是dept表中deptno为10 的一行数据。
dept部门表中也有一个deptno:如下
先以emp这张表来说:
emp共有8行数据,想要查询其中的3,4,5行,该怎么办呢?
用limit这个内置函数来解决:
SELECT * from emp limit 2,3
效果如下:
(limit 2,3) 中的 2 代表从下标为2的数据开始查,3代表向后执行3次查询。
假如改为 limit 2,0 ,虽然从下标为2的数据开始,但是0就代表查询执行0次,就不会查出任何东西!
这就是limit在mysql中起到的作用,也为数据分页作了基础。
emp中sal 代表工资, 我想将工资从小到大或者从大到小排列该怎么办呢?
用内置函数order by desc降/asc升
SELECT * from emp order by sal desc
desc代表数据从大到小排列,asc反之。
在emp表中可以发现 deptno一列中有许多重复的;
例如deptno=10,代表名字为jack,limi,两人的部门号是相同的。
向dept表中找deptno为10的那一行,可知他们所在部门为钱部。
那么我该怎么计算钱部所有员工的平均工资呢?
用内置函数group by与聚合函数avg解决:
group by分组:deptno=10的有两个,用group by 就会将这两个人分到同一组中,这个组的标志就是deptno=10
avg聚合函数:用来求某列的平均数;
SELECT emp.deptno,avg(sal) as avg from emp GROUP BY emp.deptno
效果如下:
可以发现,deptno=null的也有avg,但这个avg并没有并没有被分组,而是直接列了出来,这个暂时可忽略。
用group by需注意:
select 后面只能写被分组的字段(deptno),还有就是可以写聚合函数。如何要用where子句连接,那么where必须放在group by之前。
那么,我想求avg大于2000的该怎么办呢?
错误一: 用where限制
select deptno,avg(sal) as avg from emp group by deptno where avg>2000
错误二:将where放在group by之前
select deptno ,avg(sal) as avg from emp where avg>2000 group by deptno
为什么将where放在group by之前还是会错误呢?
用where子句也有要求:where 子句必须在group by 之前,而且where子句不可与聚合函数连用!
那该怎么办呢?
用having解决!
SELECT emp.deptno,avg(sal) as avg from emp GROUP BY emp.deptno HAVING avg>2000
效果如下:null的可暂时忽略 大于2000的 只有deptno=12的
可以发现,having 与where都是用来作条件过滤的。
having出现的目的在于,当使用分组和聚合函数后,依然可使得语句进行条件过滤!还有一处不同,having只能用在group by之后!
高级联合查询
已知,emp与dept为两张不同的表,它们之间的唯一联系就是外键depton.
那么我想查询emp表,并且将emp表中名字叫jack的所在部门也显示出来该怎么办?
jack所在的部门为钱部,在dept表里,这怎么能放在一起呢?
这里,外键depton就起到了关键的作用!
先不用外键,我们还可以这样查:
select * from emp,dept;
效果如下:
可以发现,jack与他对应的部门钱部都查了出来,但是jack这个人明明只有一个,为什么结果会有四个呢?并且其它部门也有他的名字。
这是因为当对两个集合一起查询时,两个集合中的所有行数据互相配对,jack就与dept表中的所有行一一配对,就产生了这种不符合逻辑的结果。与数学中的笛卡尔积类似。
如何解决呢?
用内连接 inner join … on + 外键!
select * from emp INNER JOIN dept on emp.deptno = dept.deptno
效果如下
内连接的目的在于,将emp表中外键depton与dept中的键depton相互匹配,如果两个depton内容相同,就将emp中的这一行与dept中古代这一行组合起来。
比如jack的depton=10,而dept中就有一个结果depton为10的。就将jack这一行与钱部这一行组合。
这样就解决了上个问题,但是又出了新的问题~~
如上图,有两列depton!一个是emp的,一个是dept的,这样该怎么办呢?
用using简写代码!
select * from emp inner join dept using(deptno)
这样depton就会只显示一个。
再看上图,我的emp中有8个员工,可是只显示出了7个,如果我想8个都显示,该怎么办呢?
用外连接!
外连接又分为左外连接left join 和 右外连接right join
假如我用右外连接,代码如下
SELECT * from emp right JOIN dept on emp.deptno = dept.deptno
效果如下:
可以发现,还是只有7个!
这就要说说外连接的用法。
在代码中,emp表总是在dept表前面的,例如
from emp right join dept 可以看出 emp排在dept前面。
right join的含义就是,以排在右边的表为主,排在左边的表为次。
left join的含义就是, 以排在左边的表为主,排在右边的表为从次。
所有上述代码,是以dept为主,emp为次。
那么我的主表dept没有给第8个员工外键,那他凭什么能显示出来呢?(可见第8个员工的depton为null)
那好,换成如下代码:
SELECT * from emp left JOIN dept on emp.deptno = dept.deptno
效果如下:
可以看见,第8个员工显示出来了!
上述代码,emp在前,dept在后,用的left join。
可知,以emp为主,dept为次!
那么dept给不给我外键都没有影响了,我是主,我就要显示出来我所有的员工~~~
如果 将emp 与dept调换位置呢? 它仍然遵循外连接的规则!大家可以推一下。
特殊的自连接:(就是自己连接自己查询)
SELECT * from emp e1 INNER JOIN emp e2 on e1.sal = e2.sal
效果如下
可以发现,emp确实与自己组合起来了!
对自恋接只有一个要求:需要根据自己表的需求使用!