MySQL函数,复合查询和内外连接
Posted 两片空白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL函数,复合查询和内外连接相关的知识,希望对你有一定的参考价值。
目录
一.函数
1.1 日期函数
- 获得年月日
- 获得时分秒
- 获得时间戳
- 在日期的基础上加上日期
- 在日期的基础上减日期
- 计算两个日期相差多少天
案例:
创建一个生日表,添加当前日期。
创建一个留言表,插入留言和当前日期时间
显示所有留言信息,发布时间只显示日期,不显示时间。
查询在2分钟内发布的留言。
1.2 字符串函数
案例:
- 获取表中的字符集
- 显示学生信息。
- 求表中字段占用字节数
- 将字段中名字有S的替换成'上海'
- 截取表中ename字段第二个到第三个字符
- 以首字母小写的方式显示所有员工的成绩。
1.3 数学函数
- 绝对值
- 向上取整
意思是:有小数直接进位
- 向下取整
意思是:有小数直接去除。
- 保留2位小数,多的小数位四舍五入。
- 生成随机数
1.4 其它函数
- 查询当前用户
- md5,对一个字符串进行md5加密,加密生成等长32位字符串,并且不会冲突。
- 显示当前使用数据库
- ifnull(val1,val2) 如果val1为空放回val2,否者返回val1。
二.复合查询
我们用一个简单的公司管理系统,有三张表emp,dept,salgrade来演示。
做这种题步骤:
- 首先找查询什么,显示什么。
- 其次找条件,where...,分组,排序,做笛卡尔积等。
2.1 基本查询
- 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J
- 按照部门号升序而雇员的工资降序排序
select * from emp order by deptno, sal desc;
- 使用年薪进行降序排序
select ifnull(12*sal+comm, 12*sal) as YearSal from emp order by YearSal desc;
-
显示工资最高的员工的名字和工作岗位
select ename, job from emp order by sal desc limit 1;
-
显示工资高于平均工资的员工信息
select * from emp where sal > (select avg(sal) from emp);
#select avg(sal) from emp结果,作为外层条件
-
显示每个部门的平均工资和最高工资
select max(sal), avg(sal) from emp group by deptno
-
显示平均工资低于 2000 的部门号和它的平均工资
select deptno, avg(sal) avgsal from emp group by deptno having avgsal < 2000;
-
显示每种岗位的雇员总数,平均工资
select avg(sal), count(*) from emp group by job;
2.2 多表查询
实际开发中往往数据来自不同的表,需要进行多表查询。
-
显示雇员名、雇员工资以及所在部门的名字
-
因为雇员名和雇员工资来自 EMP,部门名字来自于 DEPT 表,因此要联合查询。
笛卡尔积之后,俩个表中的数据冗余到了一起,所以信息都包含,然后通过加条件来得到正确的或者想要的答案。
一般将从表中的外键和主表中的主键相等,就可以得到正确的答案。
- 显示部门号为10的部门名,员工名和工资。
显示部门名,员工名,工资,条件部门号等于10。
部门名在部门表dept中,员工名和工资在员工表中emp中,需要将两表做笛卡尔积。用部门号要筛选出正确的信息,在加上条件,得到需要的信息。
select a.deptno,dname, ename, sal from dept a, emp b where a.deptno = b.deptno and a.deptno=10;
- 显示每一个员工的姓名,工资和工资级别。
需要将emp和salgrade做笛卡尔积,然后选出正确的信息。
select ename, sal, grade from emp, salgrade where emp.sal between salgrade.losal and salgrade.hisal;
2.3 自连接
自连接实际就是当前表和当前表做笛卡尔积。自己和自己做笛卡尔积。
-
显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号--empno)
显示编号和姓名,条件,找到员工编号等于FORD领导编号的员工。
用子查询:
select empno,ename from emp where empno=(select mgr from emp where ename like 'FORD');
select a.empno,a.ename from emp a, emp b where b.ename='FORD' and a.empno=b.mgr;
2.4 子查询
子查询是指嵌入在其它sql语句中的select语句,也叫嵌套查询。
一个里层select的返回值,作为外层select的条件。
2.4.1 单行子查询
里层select返回一行记录的子查询。
-
显示 SMITH 同一部门的员工
select ename, deptno from emp where ename<>'SMITH' and deptno=(select deptno from emp where ename like 'SMITH');
2.4.2 多行子查询
里层select返回多行记录的子查询。
- in关键字,查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的
查询雇员名字,岗位,工资,部门号。条件:和10部门工岗位相同,且不包含10号部门的员工。
select ename, job, sal, deptno from emp where deptno<>10 and job in (select distinct job from emp where deptno=10);
-
all 关键字;显示工资比部门 30 的所有员工的工资高的员工的姓名、工资和部门号
-
any 关键字;显示工资比部门 30 的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)
2.4.3 多列子查询
里层select返回多个列数据的子查询语句。
-
查询和 SMITH 的部门和岗位完全相同的所有雇员,不含 SMITH 本人
2.4.4 在from中使用子查询
子查询出现在from语句中,可以将子查询当做一个临时表使用。
-
显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资
select ename, emp.deptno, sal, avg_sal from emp, (select deptno,avg(sal) avg_sal from emp group by deptno) avg_table where emp.deptno=avg_table.deptno and sal>avg_sal;
-
查找每个部门工资最高的人的姓名、工资、部门、最高工资
select ename, sal, emp.deptno, max_sal from emp, (select deptno, max(sal) max_sal from emp group by deptno) tmp where emp.deptno=tmp.deptno and emp.sal=tmp.max_sal;
- 显示每个部门的信息(部门名,编号,地址)和人员数量
方法1:使用多表
select dept.dname, dept.deptno, dept.loc,count(*) '部门人数' from dept, emp where dept.deptno=emp.deptno group by dept.deptno, dept.dname, dept.loc;
方法2:使用子查询
select dept.dname, dept.deptno, dept.loc, people_num from dept, (select count(*) people_num, deptno from emp group by deptno) tmp where tmp.deptno=dept.deptno;
2.2.5 合并查询
合并查询是,可以合并多个select的结果。使用的集合操作符union,union all
- union
该操作符可以合并两张表的数据。并且会将两张表的重复数据去除,去重。
- union all
该操作符可以合并两张表的数据。但是不会去重。
将工资大于2500或职位是MANAGER的人找出来
三.表的内外连接
3.1 内连接
内连接实际上就是利用where语句对两种表形成的笛卡尔积进行筛选。我们上面的查询都是内连接,是开发中使用最多的连接。
语法:select 字段 from 表1 inner join 表2 on 连接条件 and 其它条件;
上面是内连接的规范语法,但是,我们在上面使用时,并没有写的成这样,也是可以的。
- 显示SMITH的名字和部门信息。
on和where的区别:
where是先将全部信息做笛卡尔积,即表1第一行和表2所有行组合,表1第二行和表2所有行组合,表1剩余行做同样操作。再进行where条件筛选。得到正确信息。
on是在做笛卡尔积时,根据条件筛选做笛卡尔积。即,表1中的信息,先在表2中找到和on条件匹配的数据,再进行组合。
3.2 外连接
外连接分两种,左外连接和右外连接。
3.2.1 左外连接
语法:select 字段 from 表1 left join 表2 on 连接条件;
left join 左侧表的信息全部显示。主要就是按照左侧表对右侧表进行匹配,没有显示为空。
特征:
- 如果右侧表中没有左侧表中的对应数据,右侧表的字段显示为空。
- 右侧表中有左侧表没有的字段,不会显示。
- 如果右侧表中有左侧表中的对应数据,正常显示。
- 如果右侧表中有多条重复左侧表中的对应数据,只要与左侧表信息匹配,全部对应显示。也就是显示个数不一定和左侧表行数一样,可能多于左侧表函数。
如下:
-
查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来
建立两张表:
进行左外连接:
往exam中插入重复的值:
再进行左外连接:
3.2.2 右外连接
语法:select 字段 from 表1 right join 表2 on 连接条件;
右外连接就是将右侧表信息全部显示。主要就是按照右侧表对右侧表进行匹配,没有显示为空。
特征和左外连接相同。
案例:
- 对stu表和exam表联合查询,把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要显示出来
注意:左外连接和左外连接on和必须有连接条件。
以上是关于MySQL函数,复合查询和内外连接的主要内容,如果未能解决你的问题,请参考以下文章
MySql-表的概念DQL查询语句条件查询模糊查询分组函数单行处理函数连接查询笛卡尔积现象内外自连接子查询重要关键字建表增删改查